前言:
建造者模式(Builder Pattern)提供了一种创建对象的最佳方式。它创建对象的过程是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。创建者模式隐藏了复杂对象的创建过程,它把复杂对象的创建过程加以抽象,通过子类继承或者重载的方式,动态的创建具有复合属性的对象。
特点:
- 创建对象不必知道对象内部组成的细节。
- 具体的建造者类之间是相互独立的,有利于系统的扩展。
- 过程逐步细化,而不会对其他模块产生任何影响,便于控制细节风险。
实现:
需求:客人向店长点两个汤,一份西红柿鸡蛋汤,一份紫菜蛋花汤。店里呢,有个专业做西红柿鸡蛋汤的,有个专业做紫菜蛋花汤的(别问我为啥不是一个厨师做,因为术业有专攻嘛),店长不关心汤具体怎么做的(领导肯定只在乎结果,过程关他屁事),他只要向后厨(店里请了两个专业大厨)说一声,那么厨师听到了以后自然会去煲自己负责的汤。然后煲好了给店长就行了。
分析实现:
1:创建汤的父类(Soup),创建西红柿鸡蛋汤(XIHongShiJiDanSoup)类继承父类(Soup),创建紫菜蛋花汤(ZiCaiDanHuaSoup)类继承父类(Soup)。并分别在子类中实现自己需要的食材和制作方法。
2:创建做汤的抽象接口(SoupBuild),定义煲汤的方法:makeSoup();返回值汤(Soup)。创建西红柿蛋花汤专业厨师长(XiHongShiJiDanSoupBuilder)继承SoupBuild接口,并实现煲汤的方法。创建紫菜蛋花汤专业厨师长(ZiCaiDanHuaSoupBuilder)继承SoupBuild接口,并实现煲汤的方法。
3:得到需要的汤。
4:使用测试类进行测试
建造者模式实现:
项目结构图:
相关类源码:
汤的父类:Soup
**
* 汤的父类
*/
public class Soup {
}
西红柿鸡蛋汤类:XIHongShiJiDanSoup
/**
*西红柿鸡蛋汤实体类,继承Soup类
* 类中逻辑实现均以打印的内容代替
*/
public class XIHongShiJiDanSoup extends Soup{
//其实以下这些方法中应该是创建对应的对象,并使用要有的对象完成赋值或其他事,具体逻辑需要自己去实现
public void daJiDan(){
System.out.println("打两个鸡蛋,搅拌均匀");
}
public void qieXiHongShi(){
System.out.println("洗干净西红柿切好做准备");
}
public void fanChao(){
System.out.println("鸡蛋和西红柿炒拌均匀");
}
public void jiaShui(){
System.out.println("加入水煲一会");
}
public void jiaTiaoLiao(){
System.out.println("加调料");
}
}
紫菜蛋花汤类:ZiCaiDanHuaSoup
/**
*紫菜蛋花汤实体类,继承Soup类
* 类中逻辑实现均以打印的内容代替
*/
public class ZiCaiDanHuaSoup extends Soup{
public void zhenBeiZiCai(){
System.out.println("清洗干净紫菜做准备");
}
public void shaoShui(){
System.out.println("烧开水");
}
public void xiaZiCai(){
System.out.println("紫菜下锅");
}
public void xiaJiDan(){
System.out.println("慢慢倒入搅拌均匀的鸡蛋");
}
public void jiaTiaoLiao(){
System.out.println("出锅");
}
}
抽象煲汤大厨接口:SoupBuilder
public interface SoupBuild {
public Soup makeSoup();
}
西红柿鸡蛋汤专业制作大厨:XiHongShiJiDanSoupBuilder
/**
* 西红柿鸡蛋汤专业制作大厨,继承煲汤SoupBuild接口
* 因为大厨是专业煲西红柿鸡蛋汤的嘛,所以肯定是胸有成竹。哦,不对
* 这里是胸有西红柿鸡蛋汤 XIHongShiJiDanSoup "武功秘籍"的
*/
public class XiHongShiJiDanSoupBuilder implements SoupBuild{
private XIHongShiJiDanSoup xiHongShiJiDanSoup = new XIHongShiJiDanSoup();
@Override
public Soup makeSoup() {
System.out.println("开始制作西红柿鸡蛋汤!");
xiHongShiJiDanSoup.daJiDan();
xiHongShiJiDanSoup.qieXiHongShi();
xiHongShiJiDanSoup.fanChao();
xiHongShiJiDanSoup.jiaShui();
xiHongShiJiDanSoup.jiaTiaoLiao();
return xiHongShiJiDanSoup;
}
}
紫菜蛋花汤专业制作大厨:ZiCaiDanHuaSoupBuilder
/**
* 紫菜蛋花汤专业制作大厨,继承煲汤SoupBuild接口
* 因为大厨是专业煲紫菜蛋花汤的嘛,所以肯定是胸有成竹。哦,不对
* 这里是胸有紫菜蛋花汤 XIHongShiJiDanSoup "武功秘籍"的
*/
public class ZiCaiDanHuaSoupBuilder implements SoupBuild{
private ZiCaiDanHuaSoup ziCaiDanHuaSoup = new ZiCaiDanHuaSoup();
@Override
public Soup makeSoup() {
System.out.println("开始制作紫菜蛋花蛋汤!");
ziCaiDanHuaSoup.zhenBeiZiCai();
ziCaiDanHuaSoup.shaoShui();
ziCaiDanHuaSoup.xiaZiCai();
ziCaiDanHuaSoup.xiaJiDan();
ziCaiDanHuaSoup.jiaTiaoLiao();
return ziCaiDanHuaSoup;
}
}
指挥者类,俗称店长,老大:Director
/**
* 指挥者类,俗称店长,老大
* 老大后厨中私藏了两个煲汤专业户XiHongShiJiDanSoupBuilder,ZiCaiDanHuaSoupBuilder
*/
public class Director {
private XiHongShiJiDanSoupBuilder xiHongShiJiDanSoupBuilder = new XiHongShiJiDanSoupBuilder();
private ZiCaiDanHuaSoupBuilder ziCaiDanHuaSoupBuilder = new ZiCaiDanHuaSoupBuilder();
public XIHongShiJiDanSoup makeXiHongShiJiDanSoup(){
System.out.println("厨师要开始做西红柿鸡蛋汤了!");
return (XIHongShiJiDanSoup) xiHongShiJiDanSoupBuilder.makeSoup();
}
public ZiCaiDanHuaSoup makeZiCaiDanHuaSoup(){
System.out.println("厨师要开始做紫菜蛋花汤了!");
return (ZiCaiDanHuaSoup) ziCaiDanHuaSoupBuilder.makeSoup();
}
}
测试:
/**
* 测试类,指挥者(店长)指挥做什么汤就好了,就等着出结果吧
*/
public class TestMain {
public static void main(String[] args) {
Director director = new Director();
//指挥做西红柿鸡蛋汤
XIHongShiJiDanSoup xiHongShiJiDanSoup = director.makeXiHongShiJiDanSoup();
System.out.println("///");
//指挥做紫菜蛋花汤
ZiCaiDanHuaSoup ziCaiDanHuaSoup = director.makeZiCaiDanHuaSoup();
}
}
测试结果:
总结:
从上面例子中,可以看出创建者(Director)可以把本来强依赖的东西解绑,解决了依赖问题,还提高了封装性。创建对象不必知道对象内部组成的细节,就可以得到一个“成品”。隐藏了复杂对象(XIHongShiJiDanSoup,ZiCaiDanHuaSoup)的创建过程,它把复杂对象的创建过程加以抽象(SoupBuild进行抽象),通过子类(XiHongShiJiDanSoupBuilder)继承或者重载的方式,动态的创建具有复合属性的对象(这里的XIHongShiJiDanSoup应该该是有一些属性的,为了代码量低,所以没写)。通过建造者模式,保证了每种汤的制作顺序和过程。
建造者模式与抽象工厂模式的比较:
- 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族 。
- 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象 。
- 如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽