一、写在前面的话
其实我也看过很多博主写的设计模式,多多少少的也都忘记了。
今天终于是我自己来写,希望不会那么晦涩生硬的把我想表述的都表达出来。
但愿这是个不同寻常的系列,愿它对你有所帮助。‘
二、先从一个故事入手吧
有一天,女娲捏泥人捏累了。于是乎,她就找了一个包工头,她告诉包工头说:“你帮我找几个也会捏人的神仙吧,让他们帮帮我”。于是包工头答应了,包工头问女娲,”你这捏人有没有什么约定条件啊?",女娲回答他说:“有,我这条件就是以后每个人在做自我介绍的时候顺序要可以自由控制,我让TA先说自己的名字他就要能先说自己的名字,我让TA先说自己的性别他就得先说自己的性别...”于是包工头回去找会捏人的神仙去了....
包工头找到了会捏人的神仙,可是神仙们只能捏一种性别的人呀。于是包工头把会捏男人的神仙放聚集在了一个地方,又把会捏女人的神仙聚集在了一个地方,对他们说:“各路神仙,我们这次的任务是帮助女娲捏人。现在啊我说一下最基本的捏人的规则:我们捏的人都要让女娲去规定他们自我介绍的顺序,而且大家要捏的是人,由于这个规则对每位神仙都有效所有这个规则不能说具体是什么性别的人了。”好了,我交代完了。一会女娲就要货了。大家抓紧干呀。
故事讲完了,建造模式的主要类和参与者也都在上面这个故事上了,大家记住我加粗的地方和标红的话。接下来我们用代码让神仙们捏起来!
三、那就用code捏个人吧?
分析:看样子神仙们要捏男人/女人,那就先从这两个类入手吧。
/**
* 男人
* @author liyichen
*
*/
public class Man extends AbstractHuman{
private String name;
private Integer sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
@Override
protected void sayName() {
System.out.println("我的名字是:"+this.name);
}
@Override
protected void saySex() {
System.out.println("我的性别是:"+(this.sex <= 1 ? "男" : "女"));
}
public Man(String name, Integer sex) {
super();
this.name = name;
this.sex = sex;
}
}
/**
* 女人
* @author liyichen
*
*/
public class Female extends AbstractHuman{
private String name;
private Integer sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
@Override
protected void sayName() {
System.out.println("我的名字是:"+this.name);
}
@Override
protected void saySex() {
System.out.println("我的性别是:"+(this.sex <= 1 ? "男" : "女"));
}
public Female(String name, Integer sex) {
super();
this.name = name;
this.sex = sex;
}
}
咦?AbstractHuman是什么呢?大家还记得故事中女娲的要求吗?没错啦,就是这个类。它被抽象出来了。
/**
* 要求的抽象
* @author liyichen
*
*/
public abstract class AbstractHuman {
//女娲规定的判断自我介绍顺序的flag
private Integer initSequence ;
protected abstract void sayName();
protected abstract void saySex();
public final void show() {
if(this.initSequence <= 1) {
//是男人的话就先说名字 后说 性别吧
sayName();
saySex();
}else {
// 是女人 就反过来
saySex();
sayName();
}
}
public final void setInitSequence(Integer i) {
this.initSequence = i;
}
}
接下来还差什么呢?我们会捏人的神仙还没有呢,接下来我们来构造两派神仙。
/**
* 具体会捏男娃的神仙
* @author liyichen
*
*/
public class ManBuilder extends AbstractBuilder{
private Man man = new Man("龙娃",1);
@Override
public void setInitSqe(Integer i) {
man.setInitSequence(i);
}
@Override
public AbstractHuman getHuman() {
return this.man;
}
}
**
* 具体会捏女娃的神仙
* @author liyichen
*
*/
public class FemaleBuilder extends AbstractBuilder{
private Female female = new Female("凤娃",2);
@Override
public void setInitSqe(Integer i) {
female.setInitSequence(i);
}
@Override
public AbstractHuman getHuman() {
return this.female;
}
}
咦?这里怎么又有一个AbstractBuilder这是什么类?根据男人女人的解释,我猜测他是包工头开工前说的基本捏人规则吧。没错这个类就是为了规范神仙们在捏人过程中捏的是不是规范标准符合要求的。
/**
* 抽象建造规则
* @author liyichen
*
*/
public abstract class AbstractBuilder {
//加载顺序由上层给定
public abstract void setInitSqe(Integer i);
//建造谁 由 子类决定
public abstract AbstractHumanProduct getHuman();
}
万事大全,我们神仙们已经准备好了。只等包工头一声令下就可以开工了。现在我们让包工头也闪亮登场吧。
/**
* 指挥类,最高层只找该类所要所需的类
* 注:1.指挥类需要有所有构造类的对象 (包工头得有所有神仙的联系方式)
* 2.进度(初始化顺序)由指挥官指定 (根据女娲要求她说自我介绍的顺序是什么样就是什么样子)
* @author liyichen
*
*/
public class Director {
private ManBuilder manBui = new ManBuilder();
private FemaleBuilder femaleBui = new FemaleBuilder();
private Integer initSeq = -1; //执行顺序的flag
public Man getMan() {
//指定初始化顺序
this.initSeq = 1;
manBui.setInitSqe(this.initSeq);
return (ManProduct) this.manBui.getProduct();
}
public Female getFemale() {
//指定初始化顺序
this.initSeq = 2;
femaleBui.setInitSqe(this.initSeq);
return (FemaleProduct) this.femaleBui.getProduct();
}
}
只等女娲来要人了。
**
*
* 主控类,负责调起指挥类指挥builder生产所需要的类
* @author liyichen
*
*/
public class ClientMain {
public static void main(String[] args) {
Director dir = new Director();
Man man = dir.getMan();
man.show();
Female female = dir.getFemale();
female.show();
}
}
至此我们的构造模式已经讲完了。大家可以根据每个类再反复的看一看刚才我标注的关键人和规定。怎么和类对应上的。
四、总结
其实女娲就是我们口中的上层调用者,当她需要泥人的时候她只需要找到包工头,由包工头组织各个神仙(建造者)去建造就好了。如果有一天又增加新的性别的人,只需要增加对应的类和神仙(建造者)就好了。包工头自然知道这件事,因为他需要再找新的会捏新性别的神仙。而女娲并不关心她只知道包工头能给我捏泥人(AbstractHuman)就好了。
我们来梳理一下建造模式的几个关键人物:
产品类(就是故事中的男人/女人,通常实现了模板方法(就是AbstractHuman))
抽象建造者(一般由子类实现,就是包工头的规定)
具体建造者(就是包工头找的各路神仙)
导演类(就是包工头)
那什么时候用建造模式呢?其实很简单,大家有没有发现建造模式有一个在把控运行结果的这样一个操作。所以:
1.相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用;
2.多个部件或者零件(就是介绍名字、介绍性别)、都可以装配到一个对象中,但是产生的运行结果又不同时,可以采用;
3.产品类非常复杂,或者产品类中调用的顺序不同产生了不同的效能,这个时候可以使用。
另外说一点,建造模式和工厂模式最大的不同在于:建造模式更注重的把控零件类和装配工艺(其实就是执行顺序),而工厂不关注这个问题。随同为创建类模式,但是关注点不同!
五、写在最后
希望本文对你有所帮助,另外学习无止境。有不正确的地方欢迎留言指正看到及时修正!谢谢。