- It uses a shared mechanism to hold and return a large number of objects efficiently.
- Shared flyweight objects are immutable.
- Examples include, characters and line-styles in a word processor or digit receivers in a public switched telephone network application.
- You will find flyweights mostly in utility-type applications (word processors, graphics programs, network apps).
- They are rarely used in data-driven business type applications.
- Flyweights are used internally in the .NET Framework as a string management technique to minimize memory usage for immutable strings.
Participants
Flyweight
(IApiEndPoint)
- Declares an interface through which flyweights can receive and act on extrinsic state.
ConcreteFlyweight
(EndPoint1, EndPoint2)
- Implements the Flyweight interface and adds storage for intrinsic state, if any.
- This object must be shareable.
- Any state it stores must be independent of the ConcreteFlyweight object's context.
UnsharedConcreteFlyweight
(Not Used)
- Not all Flyweight sub-classes need to be shared.
- The Flyweight interface enables sharing, but it doesn't enforce it.
FlyweightFactory
(ApiFactory)
- Creates and manages flyweight objects.
- Ensures that flyweight are shared properly.
- When a client requests a flyweight, it supplies an existing instance or creates one, if none exists.
var factory = new ApiFactory();
var endPoint1 = factory.GetEndPoint("EndPoint1");
var client1 = endPoint1.GetClient("Api/Test1");
var endPoint2 = factory.GetEndPoint("EndPoint2");
var client2 = endPoint1.GetClient("Api/Test2");
public class ApiFactory
{
private Dictionary<string, IApiEndPoint> _EndPoints = new Dictionary<string, IApiEndPoint>();
public IApiEndPoint GetEndPoint(string name)
{
IApiEndPoint endPoint = null;
if (_EndPoints.ContainsKey(name))
endPoint = _EndPoints[name];
else
{
switch (name)
{
case "EndPoint1": endPoint = new EndPoint1(); break;
case "EndPoint2": endPoint = new EndPoint2(); break;
}
_EndPoints.Add(name, endPoint);
}
return endPoint;
}
}
public interface IApiEndPoint
{
string Name { get; set; }
string Url { get; set; }
HttpClient GetClient(string route);
}
public class EndPoint1 : IApiEndPoint
{
public string Name { get; set; } = "Name1";
public string Url { get; set; } "www.Test1.com";
public HttpClient GetClient(string route) => throw new NotImplementedException();
}
public class EndPoint2 : IApiEndPoint
{
public string Name { get; set; } = "Name2";
public string Url { get; set; } = "www.Test2.com";
public HttpClient GetClient(string route) => throw new NotImplementedException();
}
Rules of Thumb
- Whereas Flyweight shows how to make lots of little objects, Facade shows how to make a single object represent an entire subsystem.
- Flyweight is often combined with Composite to implement shared leaf nodes.
- Terminal symbols within Interpreter's abstract syntax tree can be shared with Flyweight.
- Flyweight explains when and how State objects can be shared.