设计模式-建造者模式

建造者模式模式

        将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

        建造者模式第一种创建行模式,他讲客户端与包含多个部件的复杂对象的创建过程分离,客户端无需知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可。建造者模式关注如何一步一步的创建一个负责对象,不同的建造者定义了不同的建造过程。

模式结构

       Builder(抽象的建造者):他为创建一个产品对象的各个部件制定抽象接口,在该接口中一般声明两个方法,一个是创建对象属性的方法,另一个是用于返回复杂对象的方法。该类可以是抽象类,也可以是接口

     ConcreteBuilder(具体的建造者):他实现了Build接口,并重写父类方法。

     Product(产品):他是被构建的复杂对象。定义各个部件(属性),具体的建造者负责建造他的部件。并定义它的装配过程。

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

    建造者模式与抽象工厂模式都是较为复杂的创建型模式,建造者模式返回一个完整的负责的产品,抽象工厂模式返回一系列相关的产品;在抽象工厂模式中,客户端通过选择具体的工厂来生成岁需要的对象,而在建造者模式中,客户端通过执行具体建造者类型来指导导演类如何创建对象。

举例说明

      场景:游戏中的角色。

      复杂对象类:角色,其中角色类型,性别,脸型,服装,发型等都为对象的部件

package com.gm.builder.one;

/**
 * 角色对象, 充当产品,该产品由较为复杂的属性(组成部分)
 */
public class Actor {
    /**
     *  角色
     */
    private String type;
    /**
     * 性别
     */
    private String sex;
    /**
     * 脸型
     */
    private String face;
    /**
     * 服装
     */
    private String costume;
    /**
     * 发型
     */
    private String hairstyle;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getFace() {
        return face;
    }

    public void setFace(String face) {
        this.face = face;
    }

    public String getCostume() {
        return costume;
    }

    public void setCostume(String costume) {
        this.costume = costume;
    }

    public String getHairstyle() {
        return hairstyle;
    }

    public void setHairstyle(String hairstyle) {
        this.hairstyle = hairstyle;
    }

    @Override
    public String toString() {
        return "Actor{" +
                "type='" + type + '\'' +
                ", sex='" + sex + '\'' +
                ", face='" + face + '\'' +
                ", costume='" + costume + '\'' +
                ", hairstyle='" + hairstyle + '\'' +
                '}';
    }
}

  抽象建造者:声明创建复杂对象的各个部件,并通过工厂方法返回复杂对象

package com.gm.builder.one;

/**
 * 抽象建造者
 */
public abstract class ActorBuild {
    protected Actor actor = new Actor();

    /**
     * 建造角色类型
     */
    public abstract void buildType();
    /**
     * 建造性别
     */
    public abstract void buildSex();

    /**
     * 建造脸型
     */
    public abstract void buildFace();

    /**
     * 建造服装
     */
    public abstract void buildCostume();

    /**
     * 建造发型
     */
    public abstract void buildHairstyle();

    /**
     * 工厂方法,返回完成的对象
     * @return
     */
    public Actor createActor(){
        return actor;
    }

}

具体的创建者:天使创建者,英雄创建者,继承抽象建造者,并重写创建部件的方法,完成部件具体创建过程。

package com.gm.builder.one;

/**
 * 天使角色
 */
public class AngleBuild extends ActorBuild {
    @Override
    public void buildType() {
        actor.setType("天使");
    }

    @Override
    public void buildSex() {
        actor.setSex("女");
    }

    @Override
    public void buildFace() {
        actor.setFace("成熟脸");
    }

    @Override
    public void buildCostume() {
        actor.setCostume("性感的衣服");
    }

    @Override
    public void buildHairstyle() {
        actor.setHairstyle("大波浪");
    }
}




package com.gm.builder.one;

/**
 * 英雄角色
 */
public class HeroBuild extends ActorBuild {
    @Override
    public void buildType() {
        actor.setType("英雄");
    }

    @Override
    public void buildSex() {
        actor.setSex("MAN");
    }

    @Override
    public void buildFace() {
        actor.setFace("美队的脸");
    }

    @Override
    public void buildCostume() {
        actor.setCostume("钢铁侠的衣服");
    }

    @Override
    public void buildHairstyle() {
        actor.setHairstyle("美队的发型");
    }
}

导演类:其中的construct()方法进行安排创建部件的次序并逐步完成的创建。

package com.gm.builder.one;

/**
 * 角色控制器,充当导演类
 */
public class ActorController {
    /**
     * 逐步创建产品的组件
     * @param build
     * @return
     */
    public Actor construct(ActorBuild build){
        build.buildType();
        build.buildSex();
        build.buildFace();
        build.buildCostume();
        build.buildHairstyle();
        return build.createActor();
    }
}

客户端

package com.gm.builder.one;

public class Client {
    public static void main(String[] args) throws Exception{
        ActorBuild build = (ActorBuild) Class.forName("com.gm.builder.one.AngleBuild").newInstance();
        ActorController controller = new ActorController();
        Actor actor = controller.construct(build);
        System.out.println(actor);
    }
}

运行结果

Actor{type='天使', sex='女', face='成熟脸', costume='性感的衣服', hairstyle='大波浪'}

导演类深入讨论

      导演类是创建者模式的重要组成部分,控制创建对象部件的次序,并返回一个完整额对象,下面讨论几种导演类的变化形式:

1.省略导演类:

   为了简化程序结构,可将导演类和抽象建造者进行合并,在抽象建造者中提供导演类的功能。可将construct()方法使用static修饰,以方便客户端调用。则抽象建造者的代码如下:

package com.gm.builder.two;

public abstract class ActorBuild {
    protected static Actor actor = new Actor();

    /**
     * 建造角色类型
     */
    public abstract void buildType();
    /**
     * 建造性别
     */
    public abstract void buildSex();

    /**
     * 建造脸型
     */
    public abstract void buildFace();

    /**
     * 建造服装
     */
    public abstract void buildCostume();

    /**
     * 建造发型
     */
    public abstract void buildHairstyle();

    /**
     * 工厂方法1,返回完成的对象,逐步创建产品的组件,用来替换导演类
     * @return
     */
    public Actor construct(){
        this.buildType();
        this.buildSex();
        this.buildFace();
        this.buildCostume();
        this.buildHairstyle();
        return actor;
    }

    /**
     * 工厂方法2,返回完成的对象,逐步创建产品的组件,用来替换导演类
     * @return
     */
    public static Actor construct(ActorBuild build){
        build.buildType();
        build.buildSex();
        build.buildFace();
        build.buildCostume();
        build.buildHairstyle();
        return actor;
    }

}

从而客户端的方法如下:

package com.gm.builder.two;

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) throws Exception{
        //方法1
        ActorBuild build = (ActorBuild) Class.forName("com.gm.builder.two.AngleBuild").newInstance();
        Actor actor = build.construct();
        System.out.println(actor);
        //方法2
        ActorBuild build2 = (ActorBuild) Class.forName("com.gm.builder.two.HeroBuild").newInstance();
        Actor actor2 = ActorBuild.construct(build2);
        System.out.println(actor2);
    }
}

2.钩子方法引入

钩子方法通常为boolean型,方法名一般为is****(),钩子方法一边定义在抽象的建造者中。

抽象建造者;

package com.gm.builder.one;

/**
 * 抽象建造者
 */
public abstract class ActorBuild {
    protected Actor actor = new Actor();

    /**
     * 建造角色类型
     */
    public abstract void buildType();
    /**
     * 建造性别
     */
    public abstract void buildSex();

    /**
     * 建造脸型
     */
    public abstract void buildFace();

    /**
     * 建造服装
     */
    public abstract void buildCostume();

    /**
     * 建造发型
     */
    public abstract void buildHairstyle();

    /**
     * 钩子方法
     * @return
     */
    public boolean isBareheaded(){
        return false;
    }

    /**
     * 工厂方法,返回完成的对象
     * @return
     */
    public Actor createActor(){
        return actor;
    }



}

具体建造者:

package com.gm.builder.one;

/**
 * 英雄角色
 */
public class HeroBuild extends ActorBuild {
    @Override
    public void buildType() {
        actor.setType("英雄");
    }

    @Override
    public void buildSex() {
        actor.setSex("MAN");
    }

    @Override
    public void buildFace() {
        actor.setFace("美队的脸");
    }

    @Override
    public void buildCostume() {
        actor.setCostume("钢铁侠的衣服");
    }

    @Override
    public void buildHairstyle() {
        actor.setHairstyle("美队的发型");
    }
    @Override
    public boolean isBareheaded(){
        return true;
    }
}

通过引入钩子方法可以在导演类中对复杂对象进行精细化管理,不仅可以指定对象部件执行顺序,也可进行控制是否需要进行创建某个部件。

优劣势

   优势

    1.客户端无需知道产品内部组成细节,将产品本身与产品创建过程进行解耦,使得相同的创建过程创建不同的对象。

    2.每一个具体的建造者都是独立的,增加新的建造者无需修改原有类的代码,符合开闭原则

    3.可以精细化控制对象的创建过程。

  劣势

    1.建造者模式一般所创建的产品对象都有较多的共同点,如果产品之间的差异性很大,不适用该模式。

    2.产品内部变化复杂,可能会导致更多的具体建造者来进行创建,导致系统变得复杂。

适用场景

     1.需要生成的产品对象有复杂的内部结构,这些产品通常包含对个成员变量。

      2.需要生成的产品属性相互依赖,需要指定其生成顺序。

      3.对象的创建过程独立于创建该对象的类型。

      4.复杂对象的创建和使用,并使得相同创建过程可以创建不同对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值