Description
- Use sharing to support large numbers of fine-grained objects efficiently
- Split heavy objects into what can be shared (flyweight / template) and what to be configured (context)
- The heavy object can be generated on the fly from the flyweight object and the context
The Flyweight pattern generally concerns with heavy but similar objects because they may occupy big blocks of memory. So, you try to create a smaller set of template objects that can be configured on the fly to make these heavy objects. These smaller and configurable objects are called flyweights. You can reuse them in your application when you deal with many large objects. This approach helps you to reduce the consumption of big chunks of memories. Basically flyweights make one look like many.
Flyweight vs Singleton
Exemple
User.cs
|
public class User
{
public string Name { get; set; }
public override string ToString() => $"Simple user: {Name}";
}
|
Administrator.cs
|
public class Administrator : User
{
public override string ToString() => $"Admin user: {Name}";
}
|
UserFactory.cs
|
public class UserFactory
{
IDictionary<UserType, User> userTemplatesByUserType = new Dictionary<UserType, User>();
public User GetUserFromFactory(UserType userType)
{
User userTemplate = null;
if (userTemplatesByUserType.ContainsKey(userType))
{
userTemplate = userTemplatesByUserType[userType];
}
else
{
switch (userType)
{
case UserType.User:
userTemplate = new User();
userTemplatesByUserType.Add(UserType.User, userTemplate);
break;
case UserType.Administrator:
userTemplate = new Administrator();
userTemplatesByUserType.Add(UserType.Administrator, userTemplate);
break;
case UserType.Guest:
userTemplate = new Guest();
userTemplatesByUserType.Add(UserType.Guest, userTemplate);
break;
default:
throw new Exception($"Unknown user type {userType}.");
}
}
return userTemplate;
}
}
|
|
var userFactory = new UserFactory();
var user = userFactory.GetUserFromFactory(UserType.User);
user.Name = "Nicolas";
Console.WriteLine(user);
for (var i = 0; i < 10; i++)
{
// call only once the Administrator ctor then reuse the instance
user = userFactory.GetUserFromFactory(UserType.Administrator);
user.Name = $"Admin{i}";
Console.WriteLine(user);
}
|