« Flyweight pattern » : différence entre les versions

De Banane Atomic
Aller à la navigationAller à la recherche
(Page créée avec « Category:CSharp Category:Design Patterns = Description = * Use sharing to support large numbers of fine-grained objects efficiently »)
 
 
(7 versions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
[[Category:CSharp]]
[[Category:CSharp]]
[[Category:Design Patterns]]
[[Category:Design Patterns]]
= Description =
= Definition =
* Use sharing to support large numbers of fine-grained objects efficiently
Use sharing to support large numbers of fine-grained objects efficiently.
* Split heavy objects into what can be shared (flyweight / template / intrinsic data) and what to be configured (context / extrinsic data)
* The heavy object can be generated on the fly from the flyweight object and the context
* Reduce the memory cost of working with large numbers of very small objects
 
== Flyweight vs Singleton ==
* flyweight pattern is acting like a common template that can be configured as per the need
* singleton pattern allows to reuse an existing object
 
== Multithreading ==
Same problem and remedy as the Singleton pattern.
 
= Exemple =
<filebox fn='User.cs'>
public class User
{
    public string Name { get; set; }
 
    public override string ToString() => $"Simple user: {Name}";
}
</filebox>
 
<filebox fn='Administrator.cs'>
public class Administrator : User
{
    public override string ToString() => $"Admin user: {Name}";
}
</filebox>
 
<filebox fn='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;
    }
}
</filebox>
 
<kode lang='cs'>
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);
}
</kode>

Dernière version du 7 juin 2020 à 15:33

Definition

Use sharing to support large numbers of fine-grained objects efficiently.

  • Split heavy objects into what can be shared (flyweight / template / intrinsic data) and what to be configured (context / extrinsic data)
  • The heavy object can be generated on the fly from the flyweight object and the context
  • Reduce the memory cost of working with large numbers of very small objects

Flyweight vs Singleton

  • flyweight pattern is acting like a common template that can be configured as per the need
  • singleton pattern allows to reuse an existing object

Multithreading

Same problem and remedy as the Singleton pattern.

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;
    }
}
Cs.svg
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);
}