« Composite pattern » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
(2 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 2 : | Ligne 2 : | ||
[[Category:Design Patterns]] | [[Category:Design Patterns]] | ||
= Description = | = Description = | ||
Compose objects into tree structures to represent part-whole hierarchies.<br> | |||
Composite lets clients treat individual objects and compositions of objects uniformly | |||
* Treat single objects and composite objects in the same way | |||
* Arrange structured hierarchies so that single components and groups of components can be treated in the same way | |||
= Exemple = | = Exemple = | ||
<filebox fn='IComponent.cs'> | |||
public interface IComponent | |||
{ | |||
string Name { get; set; } | |||
void Add(IComponent component); | |||
void Remove(IComponent component); | |||
string Display(int depth); | |||
IComponent Find(string name); | |||
void AddSuffix(string suffix); | |||
} | |||
</filebox> | |||
<filebox fn='User.cs'> | |||
public class User : IComponent | |||
{ | |||
public string Name { get; set; } | |||
public User(string name) | |||
{ | |||
this.Name = name; | |||
} | |||
public void Add(IComponent component) | |||
{ | |||
throw new NotSupportedException("Cannot add a component to a user."); | |||
} | |||
public void Remove(IComponent component) | |||
{ | |||
} | |||
public string Display(int depth) => $"{new String('-', depth)} {Name}\n"; | |||
public IComponent Find(string name) => name.Equals(this.Name) ? this : null; | |||
public void AddSuffix(string suffix) | |||
{ | |||
Name += suffix; | |||
} | |||
} | |||
</filebox> | |||
<filebox fn='UsersGroup.cs'> | |||
public class UsersGroup : IComponent | |||
{ | |||
public string Name { get; set; } | |||
ICollection<IComponent> components; | |||
public UsersGroup(string name) | |||
{ | |||
this.components = new List<IComponent>(); | |||
this.Name = name; | |||
} | |||
public void Add(IComponent component) | |||
{ | |||
components.Add(component); | |||
} | |||
public void Remove(IComponent componentToRemove) | |||
{ | |||
if (!components.Remove(componentToRemove)) | |||
{ | |||
foreach (var component in components) | |||
{ | |||
component.Remove(componentToRemove); | |||
} | |||
} | |||
} | |||
public string Display(int depth) | |||
{ | |||
var stringBuilder = new StringBuilder(); | |||
stringBuilder.AppendLine($"{new String('-', depth)} {Name}"); | |||
foreach (var component in components) | |||
{ | |||
stringBuilder.Append(component.Display(depth + 1)); | |||
} | |||
return stringBuilder.ToString(); | |||
} | |||
public IComponent Find(string name) | |||
{ | |||
if (name.Equals(this.Name)) | |||
return this; | |||
foreach (var component in components) | |||
{ | |||
var matchingComponent = component.Find(name); | |||
if (matchingComponent != null) | |||
return matchingComponent; | |||
} | |||
return null; | |||
} | |||
public void AddSuffix(string suffix) | |||
{ | |||
Name += suffix; | |||
foreach (var component in components) | |||
{ | |||
component.AddSuffix(suffix); | |||
} | |||
} | |||
} | |||
</filebox> | |||
<kode lang='cs'> | |||
var group1 = new UsersGroup("Group1"); | |||
var user1 = new User("Nicolas"); | |||
group1.Add(user1); | |||
var user2 = new User("Guillaume"); | |||
group1.Add(user2); | |||
var group2 = new UsersGroup("Group2"); | |||
var user3 = new User("Paul"); | |||
group2.Add(user3); | |||
var user4 = new User("Marie"); | |||
group2.Add(user4); | |||
var group = new UsersGroup("Group"); | |||
group.Add(group1); | |||
group.Add(group2); | |||
var user5 = new User("Jean"); | |||
group.Add(user5); | |||
group.AddSuffix("!"); | |||
group.Remove(group.Find("Guillaume")); | |||
group.Remove(group.Find("Group2")); | |||
Console.WriteLine(group.Display(1)); | |||
</kode> |
Dernière version du 7 juin 2020 à 15:31
Description
Compose objects into tree structures to represent part-whole hierarchies.
Composite lets clients treat individual objects and compositions of objects uniformly
- Treat single objects and composite objects in the same way
- Arrange structured hierarchies so that single components and groups of components can be treated in the same way
Exemple
IComponent.cs |
public interface IComponent { string Name { get; set; } void Add(IComponent component); void Remove(IComponent component); string Display(int depth); IComponent Find(string name); void AddSuffix(string suffix); } |
User.cs |
public class User : IComponent { public string Name { get; set; } public User(string name) { this.Name = name; } public void Add(IComponent component) { throw new NotSupportedException("Cannot add a component to a user."); } public void Remove(IComponent component) { } public string Display(int depth) => $"{new String('-', depth)} {Name}\n"; public IComponent Find(string name) => name.Equals(this.Name) ? this : null; public void AddSuffix(string suffix) { Name += suffix; } } |
UsersGroup.cs |
public class UsersGroup : IComponent { public string Name { get; set; } ICollection<IComponent> components; public UsersGroup(string name) { this.components = new List<IComponent>(); this.Name = name; } public void Add(IComponent component) { components.Add(component); } public void Remove(IComponent componentToRemove) { if (!components.Remove(componentToRemove)) { foreach (var component in components) { component.Remove(componentToRemove); } } } public string Display(int depth) { var stringBuilder = new StringBuilder(); stringBuilder.AppendLine($"{new String('-', depth)} {Name}"); foreach (var component in components) { stringBuilder.Append(component.Display(depth + 1)); } return stringBuilder.ToString(); } public IComponent Find(string name) { if (name.Equals(this.Name)) return this; foreach (var component in components) { var matchingComponent = component.Find(name); if (matchingComponent != null) return matchingComponent; } return null; } public void AddSuffix(string suffix) { Name += suffix; foreach (var component in components) { component.AddSuffix(suffix); } } } |
var group1 = new UsersGroup("Group1"); var user1 = new User("Nicolas"); group1.Add(user1); var user2 = new User("Guillaume"); group1.Add(user2); var group2 = new UsersGroup("Group2"); var user3 = new User("Paul"); group2.Add(user3); var user4 = new User("Marie"); group2.Add(user4); var group = new UsersGroup("Group"); group.Add(group1); group.Add(group2); var user5 = new User("Jean"); group.Add(user5); group.AddSuffix("!"); group.Remove(group.Find("Guillaume")); group.Remove(group.Find("Group2")); Console.WriteLine(group.Display(1)); |