喝牛奶的时候,发现袋子上面写了一大块的伊利某某分公司,嘿,今天学到组合模式,正好用用实例,来更好的理解组合模式。
伊利总工厂在内蒙古,像牛奶一类的东西保质期都不长,为了让大家喝到真正的优质牛奶,伊利就在全国增加分工厂,来满足需求。
不管是总工厂还是分工厂,都有生产和销售部门。在组合模式中,这就可以说成是整体与部分可被一致对待的问题。
先来看看伊利工厂组合模式的代码:
abstract class ErieFactory //伊利工厂类
{
protected string name;
public ErieFactory(string name)
{
this .name =name ;
}
public abstract void Add(ErieFactory F);
public abstract void Remove(ErieFactory F);
public abstract void Display(int depth); //显示
public abstract void LineOfDuty();//履行职责
}
class ConcreteFactory:ErieFactory //具体工厂类
{
private List <ErieFactory >children =new List<ErieFactory> ();
public ConcreteFactory (string name):base(name)
{}
public override void Add(ErieFactory F)//增加
{
children .Add (F);
}
public override void Remove(ErieFactory F ) //移除
{
children .Remove (F);
}
public override void Display(int depth) //显示
{
Console .WriteLine (new string ('-',depth )+name);
foreach (ErieFactory componment in children )
{
componment .Display (depth + 2);
}
}
//履行职责
public override void LineOfDuty()
{
foreach (ErieFactory componment in children )
{
componment .LineOfDuty ();
}
}
}
//生产部门
class LineDepartment:ErieFactory
{
public LineDepartment (string name):base(name )
{}
public override void Add(ErieFactory F)//增加
{}
public override void Remove(ErieFactory F ) //移除
{}
public override void Display(int depth) //显示
{
Console .WriteLine (new string ('-',depth )+name);
}
//履行职责
public override void LineOfDuty()
{
Console .WriteLine ("{0} 生产优质牛奶",name );
}
}
//销售部门
class SaleDepartment:ErieFactory
{
public SaleDepartment (string name):base(name )
{}
public override void Add(ErieFactory F)//增加
{}
public override void Remove(ErieFactory F ) //移除
{}
public override void Display(int depth) //显示
{
Console .WriteLine (new string ('-',depth )+name);
}
//履行职责
public override void LineOfDuty()
{
Console .WriteLine ("{0} 只卖优质牛奶",name );
}
}
代码实现中,首先定义一个抽象的伊利工厂类,定义一个具体工厂类,他继承了伊利工厂的所有方法。
客户端代码: static void Main(string[] args)
{
ConcreteFactory root=new ConcreteFactory("伊利总工厂");
root.Add (new LineDepartment ("总工厂生产部门"));
root .Add (new SaleDepartment ("总工厂销售部门"));
ConcreteFactory comp=new ConcreteFactory ("上海分公司");
comp .Add (new LineDepartment ("上海分公司生产部门"));
comp .Add (new SaleDepartment ("上海分公司销售部门"));
root .Add (comp );
Console.WriteLine ("\n结构图:");
root .Display (1);
Console .WriteLine ("\n职责:");
root.LineOfDuty ();
Console .Read ();
}
再来看看代码结构图:
结果显示:
通过上边的实例,对于组合模式应该有点了解了,现在再来看看组合模式。
组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
来看看组合模式的结构图:
Leaf叶子节点中加上Add和Remove是为了让Component接口的所有子类都具有Add和Remove这样做的好处就是叶节点和枝节点对外界没有区别,他们具有一致的行为接口。但也有问题,Leaf本身没有这些方法,实现是没有意义的。 这种方式就叫做透明方式。
若不希望这样做,在接口Component中不声明Add和Remove方法,那么子类中的Leaf也就不需要去实现它,而在Composite声明所有用来管理子类对象的方法,这样就不会出现那个问题了,但会因为不够透明,所以树叶和树枝将不具有相同的接口,客户端的调用就需要做出相应的判断。这种方式就叫做安全方式。
何时使用:需求中体现对的是部分和整体层次的结构时
希望用户可以忽略组合对象与单个对象的不同,统一使用组合中的所有对象时
好处:组合模式可以让用户一致的使用组合结构和单个对象。