Java设计模式-建造者模式

建造者模式概述

建造者模式是较为复杂的创建型模式,它将客户端与包含多个组成部分(或部件)的复杂对象的创建过程分离,客户端无须知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可。它关注如何一步一步创建一个的复杂对象,不同的具体建造者定义了不同的创建过程,且具体建造者相互独立,增加新的建造者非常方便,无须修改已有代码,系统具有较好的扩展性。

建造者模式结构

● Builder(抽象建造者):它为创建一个产品 Product 对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是 buildPartX(),它们用于创建复杂对象的各个部件;另一类方法是 getResult(),它们用于返回复杂对象。Builder既可以是抽象类,也可以是接口。

● ConcreteBuilder(具体建造者):它实现了 Builder 接口,实现各个部件的具体构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。

● Product(产品角色):它是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。

● Director(指挥者):指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可以在其 construct() 建造方法中调用建造者对象的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥者进行交互,在客户端确定具体建造者的类型,并实例化具体建造者对象(也可以通过配置文件和反射机制),然后通过指挥者类的构造函数或者 Setter 方法将该对象传入指挥者类中。

建造者模式代码

Sunny 软件公司欲开发一个视频播放软件,为了给用户使用提供方便,该播放软件提供多种界面显示模式,如完整模式、精简模式、记忆模式、网络模式等。在不同的显示模式下主界面的组成元素有所差异,如在完整模式下将显示菜单、播放列表、主窗口、控制条等,在精简模式下只显示主窗口和控制条,而在记忆模式下将显示主窗口、控制条、收藏列表等。尝试使用建造者模式设计该软件。

结构图如下

1、播放软件外观类-Appearance

/**
 * 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 + '\'' +
                '}';
    }
}

2、定义一个接口 IBuildAppearance,构建播放器软件外观

/**
 * Author: YiFan
 * Date: 2018/12/13 16:15
 * Description: 构建视频播放软件外观
 */
public interface IBuildAppearance {

    void buildMenu();
    void buildPlayLists();
    void buildMainWindows();
    void buildControlBar();
    Appearance createAppearance();
}

3、定义三个播放器外观,实现 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;
    }
}

4、定义构造者类

/**
 * 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();
    }
}

5、客户端代码

/**
 * 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) 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

原文地址:https://www.cnblogs.com/shanyingwufeng/p/10184091.html

时间: 2024-10-27 05:37:58

Java设计模式-建造者模式的相关文章

Java设计模式——建造者模式

建造者模式(Builder Pattern)属于创建形的设计模式,使用多个简单的对象一步一步构建成一个复杂的对象. 主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定. 何时使用:一些基本部件不会变,而其组合经常变化的时候. 应用实例: 1.去肯德基,汉堡.可乐.薯条.炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的&quo

Java设计模式-建造者模式(Builder)

将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. [构建与表示分离,同构建不同表示] 与抽象工厂的区别:在建造者模式里,有个指导者,由指导者来管理建造者,用户是与指导者联系的,指导者联系建造者最后得到产品.即建造模式可以强制实行一种分步骤进行的建造过程. 建造模式是将复杂的内部创建封装在内部,对于外部调用的人来说,只需要传入建造者和建造工具,对于内部是如何建造成成品的,调用者无需关心. 工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建

Java设计模式--------建造者模式(Builder模式)

Builder模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们.用户不知道内部的具体构建细节.Builder模式是非常类似抽象工厂模式,细微的区别大概只有在反复使用中才能体会到. 为何使用建造者模式 是为了将构建复杂对象的过程和它的部件解耦.注意:是解耦过程和部件. 因为一个复杂的对象,不但有很多大量组成部分,如汽车,有很多部件:车轮.方向盘.发动机,还

设计模式—建造者模式(Builder)

title: 设计模式-建造者模式 建造者模式(Builder)是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节.建造者模式属于对象创建型模式.我们获得一个对象的时候不是直接new这个对象出来,而是对其建造者进行属性设置,然后建造者在根据设置建造出各个对象出来.建造者模式又可以称为生成器模式. 模式结构 一个标准的建造者模式包含如下角色: Builder:抽象建造者 ConcreteBuilder:具体建造者 Director

Java 设计模式 -- 复合模式之二

接着上文的鸭鸣例子:Java 设计模式 -- 复合模式之一 上文中,我们的鸭鸣实现了 装饰者模式  适配器模式  工厂模式的结合 现在,又需要进行改动了,上文,是可以统计一群鸭子的叫声,现在需要能够观察个别鸭子的行为 引入观察者模式: 任何想被观察的Quackable都必须实现下面的接口 public interface QuackObservable { public void registerObserver(Observer observer); public void notifyobs

一起学java设计模式--代理模式(结构型模式)

代理模式 应用软件所提供的桌面快捷方式是快速启动应用程序的代理,桌面快捷方式一般使用一张小图片来表示(Picture),通过调用快捷方式的run()方法将调用应用软件(Application)的run()方法.使用代理模式模拟该过程,绘制类图并编程实现. package ProxyPattern; interface Software { void run(); } class Application implements Software { public void run() { Syste

Java设计模式-代理模式之动态代理(附源码分析)

Java设计模式-代理模式之动态代理(附源码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的区别就是:动态代理是在运行时刻动态的创建出代理类及其对象.上篇中的静态代理是在编译的时候就确定了代理类具体类型,如果有多个类需要代理,那么就得创建多个.还有一点,如果Subject中新增了一个方法,那么对应的实现接口的类中也要相应的实习该方法,不符合设计模式原则. 动态代理的做法:在运行时刻,可以动态创建出一个实现了多个接口的代理类.每个代理类的对象都会关联一个表示内部处理

Java设计模式-代理模式之动态代理(附源代码分析)

Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代理是在编译的时候就确定了代理类详细类型.假设有多个类须要代理.那么就得创建多个. 另一点,假设Subject中新增了一个方法,那么相应的实现接口的类中也要相应的实现这些方法. 动态代理的做法:在执行时刻.能够动态创建出一个实现了多个接口的代理类.每一个代理类的对象都会关联一个表示内部处理逻辑的Inv

Java设计模式-代理模式之静态代理

Java设计模式-代理模式之静态代理 概念 为另一个对象提供一个替身或占位符以提供对这个对象的访问,使用代理模式创建代表对象,让代表对象控制某对象的访问,被代理对象可以是远程的对象.创建开销大的对象或需要安全控制的对象 远程代理控制访问远程对象 虚拟代理控制访问创建开销大的资源 保护代理基于权限控制对资源的访问 看如下的类图: 仔细看上面的类图,首先是Subject它为RealSubject和Proxy提供了接口,通过实现同一个接口,Proxy在RealSubject出现的地方取代它,这点和适配