长亭百川云 - 文章详情

组合器模式

Delphi研习社

39

2024-07-13

组合模式(Composite Pattern),又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示"整体-部分"的层次关系

组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式

优点

  • 高层模块调用简单

  • 节点自由增加

缺点

  • 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则

UML 图解

组合模式的角色及职责:

  • Component:这是组合中对象声明接口,在适当情况下,实现所有类共有的接口默认行为,用于访问和管理 Component 子部件,Component 可以是抽象类或者接口

  • Composite:非叶子节点,用于存储子部件,在 Component 接口中实现子部件的相关操作,比如增加(add),删除等

  • Leaf:在组合中表示叶子节点,叶子节点没有子节点(它是被管理者)

案例

这种模式使用的案例还是蛮多的,例如树形菜单的遍历、公司组织架构、文件和文件夹等等。下面就以公司的组织架构为例编写对应代码

客户端部分

program Combination;  
  
{$APPTYPE CONSOLE}  
  
{$R *.res}  
  
uses  
  System.SysUtils,  
  UnitCombination in 'UnitCombination.pas';  
  
begin  
  try  
    //创建公司节点  
    var Component := TCompany.Create('软件开发公司');  
    //创建部门节点  
    var Department := TCompany.Create('财务部');  
    //将小组节点添加到部门节点  
    department.Add(TWorkers.Create('A 组'));  
    department.Add(TWorkers.Create('B 组'));  
    //将部门节点添加到公司节点下面  
    component.Add(department);  
    //和上面类似,只是又创建了一个部门  
    var Department01 := TCompany.Create('研发部');  
    Department01.Add(TWorkers.Create('A 组'));  
    Department01.Add(TWorkers.Create('B 组'));  
    //将部门节点添加到公司节点下面  
    component.Add(Department01);  
    //遍历节点(使用的是公司节点对象,所以会显示当前公司下所有的节点)  
    Component.Print;  
  except  
    on E: Exception do  
      Writeln(E.ClassName, ': ', E.Message);  
  end;  
  readln;  
end.  

核心代码

unit UnitCombination;  
  
interface  
  
uses  
  System.Generics.Collections;  
  
type  
  //组织构成 => 对应 Component 角色  
  IOrganizationComponent = class abstract  
    procedure Print(); virtual; abstract;  
    procedure Add(OrganizationComponent: IOrganizationComponent); virtual; abstract;  
    procedure Remove(OrganizationComponent: IOrganizationComponent); virtual; abstract;  
  
  end;  
  
  //公司 => 对应 Composite 角色  
  TCompany = class(IOrganizationComponent)  
  private  
    FList: TList<IOrganizationComponent>;  
    FName: string;  
  
  public  
    procedure Add(OrganizationComponent: IOrganizationComponent); overload;  
    procedure Remove(OrganizationComponent: IOrganizationComponent); overload;  
    procedure Print(); override;  
    //带参构造  
    constructor Create(Name: string); overload;  
  end;  
  
  //员工 => 对应的是 Leaf 角色  
  TWorkers = class(IOrganizationComponent)  
  private  
    FName: string;  
  public  
   //带参构造  
    constructor Create(Name: string); overload;  
    procedure Print(); override;  
  end;  
  
implementation  
  
{ TComposite }  
  
uses  
  System.SysUtils;  
  
  
{ TCompany }  
  
procedure TCompany.Add(OrganizationComponent: IOrganizationComponent);  
begin  
  Self.FList.Add(OrganizationComponent);  
end;  
  
constructor TCompany.Create(Name: string);  
begin  
  
  self.FName := Name;  
  Self.FList := TList<IOrganizationComponent>.create();  
  
end;  
  
procedure TCompany.Print;  
begin  
  Writeln('***********' + Self.FName);  
  for var index := 0 to Self.FList.Count - 1 do  
  begin  
    var OrganizationComponent := Self.FList.Items[index];  
  
    OrganizationComponent.print();  
  end;  
end;  
  
procedure TCompany.Remove(OrganizationComponent: IOrganizationComponent);  
begin  
  Self.FList.Remove(OrganizationComponent);  
end;  
  
  
{ TWorkers }  
  
constructor TWorkers.Create(Name: string);  
begin  
  Self.FName := Name  
end;  
  
procedure TWorkers.Print;  
begin  
  
  Writeln(Self.FName)  
end;  
  
  
end.  

以上就是组合模式的玩法,古人说书上得来终觉浅,绝知此事要躬行,所以如果你在看完代码还是无法理解的话,那我建议你动手写一遍。

结语

这个设计模式其实不复杂,我在做的时候有好几次都卡壳了,所以最好还是动手写一遍。最后放一张运行效果图

xiaoguotu

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2