建造者模式是较为复杂的建立型模式,它将客户端与包含多个组成部分(或部件)的复杂对象的建立过程分离,客户端无须知道复杂对象的内部组成部分与装配方式,只须要知道所需建造者的类型便可。它关注如何一步一步建立一个的复杂对象,不一样的具体建造者定义了不一样的建立过程,且具体建造者相互独立,增长新的建造者很是方便,无须修改已有代码,系统具备较好的扩展性。java
● Builder(抽象建造者):它为建立一个产品 Product 对象的各个部件指定抽象接口,在该接口中通常声明两类方法,一类方法是 buildPartX(),它们用于建立复杂对象的各个部件;另外一类方法是 getResult(),它们用于返回复杂对象。Builder既能够是抽象类,也能够是接口。编程
● ConcreteBuilder(具体建造者):它实现了 Builder 接口,实现各个部件的具体构造和装配方法,定义并明确它所建立的复杂对象,也能够提供一个方法返回建立好的复杂产品对象。网络
● Product(产品角色):它是被构建的复杂对象,包含多个组成部件,具体建造者建立该产品的内部表示并定义它的装配过程。app
● Director(指挥者):指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,能够在其 construct() 建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端通常只须要与指挥者进行交互,在客户端肯定具体建造者的类型,并实例化具体建造者对象(也能够经过配置文件和反射机制),而后经过指挥者类的构造函数或者 Setter 方法将该对象传入指挥者类中。ide
Sunny 软件公司欲开发一个视频播放软件,为了给用户使用提供方便,该播放软件提供多种界面显示模式,如完整模式、精简模式、记忆模式、网络模式等。在不一样的显示模式下主界面的组成元素有所差别,如在完整模式下将显示菜单、播放列表、主窗口、控制条等,在精简模式下只显示主窗口和控制条,而在记忆模式下将显示主窗口、控制条、收藏列表等。尝试使用建造者模式设计该软件。函数
一、播放软件外观类-Appearanceui
/** * Author: YiFan * Date: 2018/12/13 16:08 * Description: 复杂产品类-视频播放软件外观 */ public class Appearance { // 菜单 private String menu; // 播放列表 private String playLists; // 主窗口 private String mainWindows; // 控制条 private String controlBar; public String getMenu() { return menu; } public void setMenu(String menu) { this.menu = menu; } public String getPlayLists() { return playLists; } public void setPlayLists(String playLists) { this.playLists = playLists; } public String getMainWindows() { return mainWindows; } public void setMainWindows(String mainWindows) { this.mainWindows = mainWindows; } public String getControlBar() { return controlBar; } public void setControlBar(String controlBar) { this.controlBar = controlBar; } @Override public String toString() { return "Appearance{" + "menu='" + menu + '\'' + ", playLists='" + playLists + '\'' + ", mainWindows='" + mainWindows + '\'' + ", controlBar='" + controlBar + '\'' + '}'; } }
二、定义一个接口 IBuildAppearance,构建播放器软件外观this
/** * Author: YiFan * Date: 2018/12/13 16:15 * Description: 构建视频播放软件外观 */ public interface IBuildAppearance { void buildMenu(); void buildPlayLists(); void buildMainWindows(); void buildControlBar(); Appearance createAppearance(); }
三、定义三个播放器外观,实现 IBuildAppearance 接口设计
/** * Author: YiFan * Date: 2018/12/13 16:18 * Description: 完整模式外观 */ public class FullMode implements IBuildAppearance { private Appearance appearance; public FullMode() { appearance = new Appearance(); } @Override public void buildMenu() { appearance.setMenu("显示菜单"); } @Override public void buildPlayLists() { appearance.setPlayLists("显示播放列表"); } @Override public void buildMainWindows() { appearance.setMainWindows("显示主窗口"); } @Override public void buildControlBar() { appearance.setControlBar("显示控制条"); } @Override public Appearance createAppearance() { return appearance; } } /** * Author: YiFan * Date: 2018/12/13 16:18 * Description: 精简模式外观 */ public class ReducedMode implements IBuildAppearance { private Appearance appearance; public ReducedMode() { appearance = new Appearance(); } @Override public void buildMenu() { appearance.setMenu("不显示菜单"); } @Override public void buildPlayLists() { appearance.setPlayLists("不显示播放列表"); } @Override public void buildMainWindows() { appearance.setMainWindows("显示主窗口"); } @Override public void buildControlBar() { appearance.setControlBar("显示控制条"); } @Override public Appearance createAppearance() { return appearance; } } /** * Author: YiFan * Date: 2018/12/13 16:19 * Description: 记忆模式外观 */ public class MemoryMode implements IBuildAppearance { private Appearance appearance; public MemoryMode() { appearance = new Appearance(); } @Override public void buildMenu() { appearance.setMenu("不显示菜单"); } @Override public void buildPlayLists() { appearance.setPlayLists("显示播放列表"); } @Override public void buildMainWindows() { appearance.setMainWindows("显示主窗口"); } @Override public void buildControlBar() { appearance.setControlBar("显示控制条"); } @Override public Appearance createAppearance() { return appearance; } }
四、定义构造者类code
/** * Author: YiFan * Date: 2018/12/13 16:23 * Description: 建造者-指挥者 */ public class Director { public Appearance construct(IBuildAppearance mode) { mode.buildMenu(); mode.buildPlayLists(); mode.buildMainWindows(); mode.buildControlBar(); return mode.createAppearance(); } }
五、客户端代码
/** * Author: YiFan * Date: 2018/12/13 16:26 * Description: */ public class Client { public static void main(String[] args) { // 建立Director对象 Director director = new Director(); // 建立Appearance三个引用变量 Appearance appearance1, appearance2, appearance3; // 建造者经过完整模式构建外观 appearance1 = director.construct(new FullMode()); // 建造者经过精简模式构建外观 appearance2 = director.construct(new ReducedMode()); // 建造者经过记忆模式构建外观 appearance3 = director.construct(new MemoryMode()); System.out.println(appearance1); System.out.println(appearance2); System.out.println(appearance3); } }
直接结果:
Appearance{menu='显示菜单', playLists='显示播放列表', mainWindows='显示主窗口', controlBar='显示控制条'} Appearance{menu='不显示菜单', playLists='不显示播放列表', mainWindows='显示主窗口', controlBar='显示控制条'} Appearance{menu='不显示菜单', playLists='显示播放列表', mainWindows='显示主窗口', controlBar='显示控制条'}
建造者模式的核心在于如何一步步构建一个包含多个组成部件的完整对象,使用相同的构建过程构建不一样的产品,在软件开发中,若是咱们须要建立复杂对象并但愿系统具有很好的灵活性和可扩展性能够考虑使用建造者模式。
(1) 在建造者模式中,客户端没必要知道产品内部组成的细节,将产品自己与产品的建立过程解耦,使得相同的建立过程能够建立不一样的产品对象。
(2) 每个具体建造者都相对独立,而与其余的具体建造者无关,所以能够很方便地替换具体建造者或增长新的具体建造者,用户使用不一样的具体建造者便可获得不一样的产品对象。因为指挥者类针对抽象建造者编程,增长新的具体建造者无须修改原有类库的代码,系统扩展方便,符合“开闭原则”
(3) 能够更加精细地控制产品的建立过程。将复杂产品的建立步骤分解在不一样的方法中,使得建立过程更加清晰,也更方便使用程序来控制建立过程。
(1) 建造者模式所建立的产品通常具备较多的共同点,其组成部分类似,若是产品之间的差别性很大,例如不少组成部分都不相同,不适合使用建造者模式,所以其使用范围受到必定的限制。
(2) 若是产品的内部变化复杂,可能会致使须要定义不少具体建造者类来实现这种变化,致使系统变得很庞大,增长系统的理解难度和运行成本。
(1) 须要生成的产品对象有复杂的内部结构,这些产品对象一般包含多个成员属性。
(2) 须要生成的产品对象的属性相互依赖,须要指定其生成顺序。
(3) 对象的建立过程独立于建立该对象的类。在建造者模式中经过引入了指挥者类,将建立过程封装在指挥者类中,而不在建造者类和客户类中。
(4) 隔离复杂对象的建立和使用,并使得相同的建立过程能够建立不一样的产品。