OOAD(面向对象分析和设计)GRASP之创建者模式(Creator)又称生成器模式学习笔记
说OOAD是一门玄学,一点都不为过。又或许是因为我之前一直没有很好的建立面向对象的思想,更有可能是因为练得不够多。。。总之,一直没能很好理解,哪怕把一本叫做《UML和模式应用》的书翻来覆去好多遍还是没懂。这种感觉吧,像是把一个很难咀嚼的东西硬是吞了下去,刺激胃产生了强烈反应,可惜一堆胃酸还是没能把这东西溶解,反倒是喝了肌酸的感觉。但是,喜大普奔的是,就在刚才,我终于觉得我好像顿悟了些什么。顺便《大话设计模式》是一本好书!浅显易懂。
————————————————————————————————————————————————————————————————
创建者模式,顾名思义,先问一个问题:谁创建了对象X?
书上说:你可以依靠LRG(低表示差异),来从领域模型中获得灵感。
可惜我没太搞懂LRG和领域模型的精髓,所以这句话对我来说是废话。
——————————————————————————————————
那么我们不防先把此模式的角色拎出来:
大致有四种角色:
建造者(Builder):只是指明抽象接口
具体建造者(ConcreteBuilder):用来实现Builder的接口以构造和装配该产品的各个部件
指挥者(Director):指挥(如何造)并构造一个使用Builder接口的对象
产品(Product):表示被构造的复杂对象。理解成一些小零件
把四种角色区分好之后,我们就可以分别定义它们,以及它们之间的关系(这里,我们以上帝创造了人来举例):
-
建造者(Builder),即上帝,上帝创建了人。那为了创建人,上帝要怎么做?这个怎么做,即builder这个类的方法。人有四肢,所以上帝要先创建头(head)、躯干(body)、手(arm)、腿(leg)。另外,职责驱动设计,上帝的职责最后是要创建一个人出来的,所以builder还要通过协作来创建人(person)这个对象,需要makeperson这个方法。于是,创建者的类就被我们画了出来。
-
具体建造者(ConcreteBuilder),即具体的人(person),人分胖(FatBuilderPerson)、瘦(SilmBuilderPerson)、美(BeautyBuilderPerson)、丑(UglyBuilderPerson),具体创建者应该继承自创造者(builder),因为不论是胖瘦美丑,都是一个人,都拥有四肢。如此,具体建造者(Concretebuilder)的类我们也画出来了。
-
指挥者(Director),指挥者是指挥如何把四肢这些部位并在一起,成为真正的人的。所以指挥者需要有一个buildperson的方法。那么指挥者的类也画出来了。
-
产品(Product),顾名思义,就是一些部件了,在这个例子中,所谓产品具体就是指人的四肢。那么产品这个类也出来了。
知道它们的意义和相互之间的关系,我们可以画出此模式的完整类图啦。
那么相应的代码实现也就简单啦:
// 要建造的产品 public class Person { public string Head { get; set; } public string Body { get; set; } public string Arm { get; set; } public string Leg { get; set; } } // 定义创建者接口,实现者必须实现该接口中定义的所有抽象方法,防止实现者疏忽而遗漏某个部件的创建 public abstract class Builder { protected Person Person { get; set; } public Builder() { Person = new Person(); } // 建造头 public abstract void BuildHead(); // 建造身体 public abstract void BuildBody(); // 建造胳膊 public abstract void BuildArm(); // 建造腿 public abstract void BuildLeg(); // 返回生成好的对象,这是一个具体方法,每个子类都可以使用它来返回一个已经创建成功的对象 public Person MakePerson() { return Person; } } // 建造者的具体实现,这里是要建造出一个瘦子 public class SilmPersonBuilder : Builder { public SilmPersonBuilder() { Person = new Person(); } public override void BuildHead() { Person.Head = "瘦子的脑袋"; } public override void BuildBody() { Person.Body = "瘦子的身体"; } public override void BuildArm() { Person.Arm = "瘦子的胳膊"; } public override void BuildLeg() { Person.Leg = "瘦子的腿"; } } // 建造者的具体实现,这里是要建造出一个胖子 public class FatPersonBuilder : Builder { public override void BuildHead() { Person.Head = "胖子的脑袋"; } public override void BuildBody() { Person.Body = "胖子的身体"; } public override void BuildArm() { Person.Head = "胖子的胳膊"; } public override void BuildLeg() { Person.Head = "胖子的腿"; } } // 建造者模式中的指挥者 public class PersonDirector { Builder builder; public PersonDirictor(Builder personBuilder) { builder = personBuilder; } // 指挥创建一个人的过程,并返回创建成功的产品 public Person BuildPerson() { builder.BuildHead(); builder.BuildBody(); builder.BuildArm(); builder.BuildLeg(); return builder.MakePerson(); } }
创建者模式(Creator)的意义和优点:能够将复杂对象的构建和它的表示分离,使同样的构建过程,可以创造不同的表示。对于用户来说,只要给定建造类型不需要知道具体建造过程和细节了。但缺点是内部细节不容易修改。
以上,如有不足请多多指正!