设计模式 - 建造者模式
1、建造者模式概念
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
基本类图:
2、角色
(1)Builder(抽象建造者)
它为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是buildPartX(),它们用于创建复杂对象的各个部件;另一类方法是getResult(),它们用于返回复杂对象。Builder既可以是抽象类,也可以是接口。
(2)ConcreteBuilder(具体建造者)
它实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
(3)Product(产品角色)
它是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。
(4)Director(指挥者)
指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其construct()建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者Setter方法将该对象传入指挥者类中。
3、为什么使用建造者模式
(1) 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
(2) 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的 产品对象。由于指挥者类针对抽象建造者编程,增加新的具体建造者无须修改原有类库的代码,系统扩展方便,符合“开闭原则”。
(3) 可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
4、建造者模式缺点
(1) 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,例如很多组成部分都不相同,不适合使用建造者模式,因此其使用范围受到一定的限制。
(2) 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,增加系统的理解难度和运行成本。
5、使用场景
(1) 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
(2) 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
(3) 对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。
(4) 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。
6、代码实例
类图:
6.1 产品角色(复杂对象)
/** * 视频播放软件 * * @since 2016.05.17 * */ public class VideoSoftware { /** * 菜单 */ private String menu; /** * 播放列表 */ private String playList; /** * 主窗口 */ private String mainWindow; /** * 控制条 */ private String controlStrip; /** * 收藏列表 */ private String markedList; public String getMenu() { return menu; } public void setMenu(String menu) { this.menu = menu; } public String getPlayList() { return playList; } public void setPlayList(String playList) { this.playList = playList; } public String getMainWindow() { return mainWindow; } public void setMainWindow(String mainWindow) { this.mainWindow = mainWindow; } public String getControlStrip() { return controlStrip; } public void setControlStrip(String controlStrip) { this.controlStrip = controlStrip; } public String getMarkedList() { return markedList; } public void setMarkedList(String markedList) { this.markedList = markedList; } @Override public String toString() { StringBuffer str = new StringBuffer(); if(null != menu && !menu.equals("")){ str.append(menu + ","); } if(null != playList && !playList.equals("")){ str.append(playList + ","); } if(null != mainWindow && !mainWindow.equals("")){ str.append(mainWindow + ","); } if(null != controlStrip && !controlStrip.equals("")){ str.append(controlStrip + ","); } if(null != markedList && !markedList.equals("")){ str.append(markedList + ","); } return str.append("ok").toString(); } }
6.2 抽象建造者
/** * 视频播放软件抽象建造类 * * @since 2016.05.17 * */ public abstract class VideoBuilder { //视频播放软件 protected VideoSoftware videoSoftware = new VideoSoftware(); /** * 建造菜单 */ public abstract void buildMenu(); /** * 建造播放列表 */ public abstract void buildPlayList(); /** * 建造主窗口 */ public abstract void buildMainWindow(); /** * 建造控制条 */ public abstract void buildControlStrip(); /** * 建造收藏列表 */ public abstract void buildMarkedList(); /** * 是否建造菜单 */ public boolean isMenu(){ return false; } /** * 是否建造播放列表 */ public boolean isPlayList(){ return false; } /** * 是否建造主窗口 */ public boolean isMainWindow(){ return false; } /** * 是否建造控制条 */ public boolean isControlStrip(){ return false; } /** * 是否建造收藏列表 */ public boolean isMarkedList(){ return false; } /** * 创建视频软件 */ public VideoSoftware createVideo(){ return videoSoftware; } }
6.3 具体建造者
/** * 完整模式构建视频播放软件 * * @since 2016.05.17 * */ public class FullModelVidel extends VideoBuilder { @Override public void buildMenu() { videoSoftware.setMenu("菜单"); } @Override public void buildPlayList() { videoSoftware.setPlayList("播放列表"); } @Override public void buildMainWindow() { videoSoftware.setMainWindow("主窗口"); } @Override public void buildControlStrip() { videoSoftware.setControlStrip("控制条"); } @Override public void buildMarkedList() { } @Override public boolean isMenu() { return true; } @Override public boolean isPlayList() { return true; } @Override public boolean isMainWindow() { return true; } @Override public boolean isControlStrip() { return true; } }
/** * 精简模式构建视频播放软件 * * @since 2016.05.17 * */ public class SimpleModelVidel extends VideoBuilder { @Override public void buildMenu() { } @Override public void buildPlayList() { } @Override public void buildMainWindow() { videoSoftware.setMainWindow("主窗口"); } @Override public void buildControlStrip() { videoSoftware.setControlStrip("控制条"); } @Override public void buildMarkedList() { } @Override public boolean isMainWindow() { return true; } @Override public boolean isControlStrip() { return true; } }
6.4 指挥者
/** * 创建具体的视频播放软件 * * @since 2016.05.17 * */ public class VideoPlay { private VideoBuilder videoBuilder; public VideoPlay(VideoBuilder videoBuilder) { this.videoBuilder = videoBuilder; } /** * 创建具体的视频播放软件 * * @return VideoSoftware */ public VideoSoftware createVideo(){ if(videoBuilder.isMenu()){ videoBuilder.buildMenu(); } if(videoBuilder.isPlayList()){ videoBuilder.buildPlayList(); } if(videoBuilder.isMainWindow()){ videoBuilder.buildMainWindow(); } if(videoBuilder.isControlStrip()){ videoBuilder.buildControlStrip(); } if(videoBuilder.isMarkedList()){ videoBuilder.buildMarkedList(); } return videoBuilder.createVideo(); } }
6.5 测试
public class Test { public static void main(String[] args) { VideoBuilder videoBuilder = new FullModelVidel(); VideoPlay videoPlay = new VideoPlay(videoBuilder); VideoSoftware videoSoftware = videoPlay.createVideo(); System.out.println("完整模式:" + videoSoftware.toString()); videoBuilder = new SimpleModelVidel(); videoPlay = new VideoPlay(videoBuilder); videoSoftware = videoPlay.createVideo(); System.out.println("精简模式:" + videoSoftware.toString()); } } 结果: 完整模式:菜单,播放列表,主窗口,控制条,ok 精简模式:主窗口,控制条,ok
以上内容参考如下网址作者所写,对此表示感谢!
网址:http://blog.csdn.net/lovelion/article/details/7426855