简单案例:
1.组装一部手机,包括组装屏幕、相机、主板、外壳等
2.手机有不同的品牌:苹果、华为、小米等
public abstract class AbstractBuildPhone { protected abstract void buildScreen(); protected abstract void buildCamera(); protected abstract void buildMainBoard(); protected abstract void buildCasing(); public void assemble() { System.out.println("开始组装。。。"); buildScreen(); buildCamera(); buildMainBoard(); buildCasing(); System.out.println("组装完成。。。"); } }
public class IPhoneBuilder extends AbstractBuildPhone{ @Override public void buildScreen() { System.out.println("组装iPhone的屏幕"); } @Override public void buildCamera() { System.out.println("组装iPhone的相机"); } @Override public void buildMainBoard() { System.out.println("组装iPhone的主板"); } @Override public void buildCasing() { System.out.println("组装iPhone的外壳"); } }
public class Test { public static void main(String[] args) { IPhoneBuilder builder = new IPhoneBuilder(); builder.assemble(); } }
传统方式分析:
1.代码简单,容易理解和实现
2.程序结构过于简单,没有设计缓存层对象,不利于程序的扩展和维护。这种方案把产品和创建过程封装在了一起,耦合性增强。
3.需要把产品和创建过程解耦。
2.1 建造者模式简介:
2.2 建造者模式的四个角色
2.3 建造者模式完成案例
//product 产品 public class Phone { private String name; private String screen; private String camera; private String mainBoard; private String casing; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getScreen() { return screen; } public void setScreen(String screen) { this.screen = screen; } public String getCamera() { return camera; } public void setCamera(String camera) { this.camera = camera; } public String getMainBoard() { return mainBoard; } public void setMainBoard(String mainBoard) { this.mainBoard = mainBoard; } public String getCasing() { return casing; } public void setCasing(String casing) { this.casing = casing; } @Override public String toString() { return "Phone{" + "name='" + name + '\'' + ", screen='" + screen + '\'' + ", camera='" + camera + '\'' + ", mainBoard='" + mainBoard + '\'' + ", casing='" + casing + '\'' + '}'; } }
//抽象建造类 public abstract class PhoneBuilder { Phone phone = new Phone(); protected abstract void buildScreen(Phone phone); protected abstract void buildCamera(Phone phone); protected abstract void buildMainBoard(Phone phone); protected abstract void buildCasing(Phone phone); public Phone assemble() { buildScreen(phone); buildCamera(phone); buildMainBoard(phone); buildCasing(phone); return phone; } }
//具体建造类 public class HuaWeiPhoneBuilder extends PhoneBuilder { @Override protected void buildScreen(Phone phone) { phone.setScreen("京东方"); } @Override protected void buildCamera(Phone phone) { phone.setCamera("徕卡"); } @Override protected void buildMainBoard(Phone phone) { phone.setMainBoard("海思"); } @Override protected void buildCasing(Phone phone) { phone.setName("Mate40 pro"); phone.setCasing("华强北"); } }
//指挥者 public class PhoneDirector { private PhoneBuilder phoneBuilder = null; public PhoneDirector(PhoneBuilder phoneBuilder) { this.phoneBuilder = phoneBuilder; } public void setPhoneBuilder(PhoneBuilder phoneBuilder) { this.phoneBuilder = phoneBuilder; } public Phone constrcutPhone() { return phoneBuilder.assemble(); } }
public class Test { public static void main(String[] args) { HuaWeiPhoneBuilder hw = new HuaWeiPhoneBuilder(); PhoneDirector director = new PhoneDirector(hw); Phone phone = director.constrcutPhone(); System.out.println(phone); } }
2.4 建造者模式分析
1.客户端不用知道产品内部的细节,将产品本身与产品的创建过程解耦,相同的创建过程可以创建不同的产品对象。
2.每一个具体建造者都相互独立,与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户用不同的具体建造者即可得到不同的产品对象。
3.可以更加精确地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰, 也更方便使用程序来控制创建过程。
4.增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”。
5.建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
6.如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,因此在这种情况下,要考虑是否选择建造者模式。
7.抽象工厂模式 VS 建造者模式
抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产即可。而建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品