生成器模式builder

生成器模式即建造者模式builder,是创建型的设计模式,主要的目的是封装一个对象的构造过程,并运行按步骤构造,我们所熟知的StringBuilder和StringBuffer就是采用这种模式进行容量扩展的。

  • [类]

StringBuilder 实现的源码

public class AbstractStringBuilder {
    protected char[] value;

    protected int count;

    public AbstractStringBuilder(int capacity) {
        count = 0;
        value = new char[capacity];
    }

    public AbstractStringBuilder append(char c) {
        ensureCapacityInternal(count + 1);
        value[count++] = c;
        return this;
    }

    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0)
            expandCapacity(minimumCapacity);
    }

    void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();
            newCapacity = Integer.MAX_VALUE;
        }
        value = Arrays.copyOf(value, newCapacity);
    }
}
public class StringBuilder extends AbstractStringBuilder {
    public StringBuilder() {
        super(16);
    }

    @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }
}
public class Client {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        final int count = 26;
        for (int i = 0; i < count; i++) {
            sb.append((char) ('a' + i));
        }
        System.out.println(sb.toString());
    }
}

生成器就是就简单的可生成的组件拼装为一个复杂的组件的过程,生成器模式构建对象的时候,对象通常构建的过程中需要多个步骤,就像我们例子中的先有主机,再有显示屏,再有鼠标等等,生成器模式的作用就是将这些复杂的构建过程封装起来。 工厂模式构建对象的时候通常就只有一个步骤,调用一个工厂方法就可以生成一个对象。

但是其实StringBuilder是一个不标准的生成器模式,它没有Director

我们再来看个例子体会一下

package Builder;

public class Computer {
    public String master;
    public String screen;
    public String keyboard;
    public String mouse;
    public String audio;
    public void setMaster(String master) {
        this.master = master;
    }
    public void setScreen(String screen) {
        this.screen = screen;
    }
    public void setKeyboard(String keyboard) {
        this.keyboard = keyboard;
    }
    public void setMouse(String mouse) {
        this.mouse = mouse;
    }
    public void setAudio(String audio) {
        this.audio = audio;
    }
}
然后我们建立一个抽象的builder类:

package Builder;

public abstract class ComputerBuilder {
    
    protected Computer computer;
    
    public Computer getComputer() {
        return computer;
    }
    
    public void buildComputer() {
        computer = new Computer();
        System.out.println("生成了一台电脑!!!");
    }

    public abstract void buildMaster();
    public abstract void buildScreen();
    public abstract void buildKeyboard();
    public abstract void buildMouse();
    public abstract void buildAudio();
}
然后我们实现两个具体的builder类,分别是惠普电脑的builder和戴尔电脑的builder

package Builder;

public class HPComputerBuilder extends ComputerBuilder {

    @Override
    public void buildMaster() {
        // TODO Auto-generated method stub
        computer.setMaster("i7,16g,512SSD,1060");
        System.out.println("(i7,16g,512SSD,1060)的惠普主机");
    }

    @Override
    public void buildScreen() {
        // TODO Auto-generated method stub
        computer.setScreen("1080p");
        System.out.println("(1080p)的惠普显示屏");
    }

    @Override
    public void buildKeyboard() {
        // TODO Auto-generated method stub
        computer.setKeyboard("cherry 青轴机械键盘");
        System.out.println("(cherry 青轴机械键盘)的键盘");
    }

    @Override
    public void buildMouse() {
        // TODO Auto-generated method stub
        computer.setMouse("MI 鼠标");
        System.out.println("(MI 鼠标)的鼠标");
    }

    @Override
    public void buildAudio() {
        // TODO Auto-generated method stub
        computer.setAudio("飞利浦 音响");
        System.out.println("(飞利浦 音响)的音响");
    }
}
package Builder;

public class DELLComputerBuilder extends ComputerBuilder {
    
    @Override
    public void buildMaster() {
        // TODO Auto-generated method stub
        computer.setMaster("i7,32g,1TSSD,1060");
        System.out.println("(i7,32g,1TSSD,1060)的戴尔主机");
    }

    @Override
    public void buildScreen() {
        // TODO Auto-generated method stub
        computer.setScreen("4k");
        System.out.println("(4k)的dell显示屏");
    }

    @Override
    public void buildKeyboard() {
        // TODO Auto-generated method stub
        computer.setKeyboard("cherry 黑轴机械键盘");
        System.out.println("(cherry 黑轴机械键盘)的键盘");
    }

    @Override
    public void buildMouse() {
        // TODO Auto-generated method stub
        computer.setMouse("MI 鼠标");
        System.out.println("(MI 鼠标)的鼠标");
    }

    @Override
    public void buildAudio() {
        // TODO Auto-generated method stub
        computer.setAudio("飞利浦 音响");
        System.out.println("(飞利浦 音响)的音响");
    }


}
然后我们实现一个director类:

package Builder;

public class Director {
    
    private ComputerBuilder computerBuilder;

    public void setComputerBuilder(ComputerBuilder computerBuilder) {
        this.computerBuilder = computerBuilder;
    }
    
    public Computer getComputer() {
        return computerBuilder.getComputer();
    }
    
    public void constructComputer() {
        computerBuilder.buildComputer();
        computerBuilder.buildMaster();
        computerBuilder.buildScreen();
        computerBuilder.buildKeyboard();
        computerBuilder.buildMouse();
        computerBuilder.buildAudio();
    }

}
最后我们测试一下代码:

package Builder;

public class ComputerCustomer {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Director director = new Director();
        
        ComputerBuilder hp = new HPComputerBuilder();
        
        director.setComputerBuilder(hp);
        
        director.constructComputer();
        
        //get the pc
        Computer pc = director.getComputer();
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • HeadFirst设计模式

    抽象父类只负责实现相应功能不用管具体是哪一个实现。 子类想调用哪一个行为,就new一个新的行为。

    黑白格
  • Java 必备面试代码

    黑白格
  • Java 工厂 Simple Factory&Factory&Abstract Factory

    使用简单工厂的目的是创建一个对象时,不向客户暴漏内部的细节,并提供创建对象的通用接口。

    黑白格
  • 面试官亲述:如何利用设计模式改善业务代码

    在业务部门的开发中,大多数的我们在完成的业务的各种需求和提供解决方案,很多场景下的我们通过 CRUD 就能解决问题,但是这样的工作对技术人的提升并不多,如何让自...

    程序员白楠楠
  • Java-策略设计模式

    今天 我们来学习一下策略模式,什么是策略模式呢?比如我们一个功能的实现可以有多个策略去选择,比如:出行方式可以选择:共享单车,拼车,私家车,出租等。如果将这个出...

    android_薛之涛
  • Java面向对象之抽象类,接口

    抽象类: 含有抽象方法的类被声明为抽象类 抽象方法由子类去实现 含有抽象方法的类必须被声明为抽象类 抽象类被子类继承,子类(如果不是抽象类)必须重写抽象类中...

    二十三年蝉
  • 依赖注入容器-- Autofac

    Autofac---Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上非常高...

    小世界的野孩子
  • java设计模式(9)-桥接模式

    这篇推文分享一下桥接模式,JDBC原理也是运用了桥接模式,先设置驱动名称,链接,来获得数据库链接,降低耦合,减少维护

    爱敲代码的猫
  • 去吧!设计模式之桥接模式

    张风捷特烈
  • 设计模式 接口隔离原则

    接着,要进行更改了。对好看的定义,发生了改变,那么就应该改变PettyGirl中的内容,但是已经在接口中定义了。那么就有问题了。即,接口承担的内容过多导致

    mySoul

扫码关注云+社区

领取腾讯云代金券