« Composite pattern » : différence entre les versions
Apparence
(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));
|