zoukankan      html  css  js  c++  java
  • 设计模式(4)——建造者模式

    1. 前文汇总

    「补课」进行时:设计模式系列

    2. 建造者模式定义

    建造者模式(Builder Pattern)也叫做生成器模式,其定义如下:

    Separate the construction of a complex object from its representation sothat the same construction process can create different representations.(将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)

    通用类图:

    • Product: 产品类,通常是实现了模板方法模式,也就是有模板方法和基本方法。
    • Builder: 抽象建造者,规范产品的组建,一般是由子类实现。
    • ConcreteBuilder: 具体建造者,实现抽象类定义的所有方法,并且返回一个组建好的对象。
    • Director: 导演类,负责安排已有模块的顺序,然后告诉 Builder 开始建造。

    通用代码示例:

    Product 产品类:

    public class Product {
        public void doSomething() {
            // 业务处理
        }
    }
    

    Builder 抽象建造者:

    public abstract class Builder {
        // 设置产品不同的部分,用来获得不同的产品
        abstract void setPart();
        // 建造产品
        abstract Product buildProduct();
    }
    

    ConcreteBuilder 具体建造者:

    public class ConcreteProduct extends Builder{
        private Product product = new Product();
        @Override
        void setPart() {
            // 独特的处理逻辑
        }
    
        @Override
        Product buildProduct() {
            return product;
        }
    }
    

    Director 导演类:

    public class Director {
        private Builder builder = new ConcreteProduct();
        public Product getProduct() {
            builder.setPart();
            // 设置不同的 part ,生产不同的零件
            return builder.buildProduct();
        }
    }
    

    3. 通过建造者模式造一辆共享单车

    接下来使用建造者模式造一辆共享单车。

    经历过共享单车大战之后,现在共享单车还在运营活着的也没几家了,在大街上比较常看到的有美团单车和哈罗单车,先创建一个抽象的产品类:

    public abstract class AbstractBike {
        // 各个零件制造顺序
        private ArrayList<String> sequence = new ArrayList<> ();
        // 自行车车架
        protected abstract void frame();
        // 自行车座位
        protected abstract void seat();
        // 自行车轮子
        protected abstract void tire();
        // 生产方法
        final public void createBike() {
            for (int i = 0; i < sequence.size(); i++) {
                String actionName = this.sequence.get(i);
                if (actionName.equalsIgnoreCase("frame")) {
                    this.frame();
                } else if (actionName.equalsIgnoreCase("seat")) {
                    this.seat();
                } else if (actionName.equalsIgnoreCase("tire")) {
                    this.tire();
                }
            }
        }
    
        final public void setSequence(ArrayList sequence) {
            this.sequence = sequence;
        }
    }
    

    在这个产品类中,定义了三个零件和一个零件的制造顺序,在单车的生产方法中,通过循环制造顺序,可以制造的顺序进行控制。

    接下来是两个具体的产品类:

    public class HelloBike extends AbstractBike {
        @Override
        protected void frame() {
            System.out.println("现在开始生产一个哈罗车架");
        }
    
        @Override
        protected void seat() {
            System.out.println("现在开始生产一个哈罗座位");
        }
    
        @Override
        protected void tire() {
            System.out.println("现在开始生产两个哈罗轮胎");
        }
    }
    
    public class MeituanBike extends AbstractBike {
        @Override
        protected void frame() {
            System.out.println("现在开始生产一个美团车架");
        }
    
        @Override
        protected void seat() {
            System.out.println("现在开始生产一个美团座位");
        }
    
        @Override
        protected void tire() {
            System.out.println("现在开始生产两个美团轮胎");
        }
    }
    

    接下来创建一个抽象的 Builder :

    public abstract class Builder {
        // 创建一个生产顺序模型
        public abstract void setSequence(ArrayList<String> sequence);
        // 生产完成后获取这个车辆模型
        public abstract AbstractBike getBike();
    }
    

    然后是两个具体的建造者:

    public class HelloBuilder extends Builder {
        private HelloBike helloBike = new HelloBike();
        @Override
        public void setSequence(ArrayList<String> sequence) {
            this.helloBike.setSequence(sequence);
        }
    
        @Override
        public AbstractBike getBike() {
            return this.helloBike;
        }
    }
    
    public class MeituanBuilder extends Builder {
        private MeituanBike meituanBike = new MeituanBike();
        @Override
        public void setSequence(ArrayList<String> sequence) {
            this.meituanBike.setSequence(sequence);
        }
    
        @Override
        public AbstractBike getBike() {
            return this.meituanBike;
        }
    }
    

    最后是一个导演类:

    public class Director {
        private ArrayList<String> sequence = new ArrayList<>();
        private HelloBuilder helloBuilder = new HelloBuilder();
        private MeituanBuilder meituanBuilder = new MeituanBuilder();
    
        public HelloBike getHelloBike() {
            this.sequence.clear();
            // 自定义生产的顺序
            this.sequence.add("frame");
            this.sequence.add("seat");
            this.sequence.add("tire");
            this.helloBuilder.setSequence(sequence);
            return (HelloBike) this.helloBuilder.getBike();
        }
    
        public MeituanBike getMeituanBike() {
            this.sequence.clear();
            // 定义生产的顺序
            this.sequence.add("seat");
            this.sequence.add("tire");
            this.sequence.add("frame");
            this.meituanBuilder.setSequence(sequence);
            return (MeituanBike) this.meituanBuilder.getBike();
        }
    }
    

    然后写一个 Test 类进行一下测试:

    public class Test {
        public static void main(String[] args) {
            Director director = new Director();
            director.getHelloBike().createBike();
        }
    }
    

    运行结果是:

    现在开始生产一个哈罗车架
    现在开始生产一个哈罗座位
    现在开始生产两个哈罗轮胎
    

    最后放一个这个示例的 UML 类图:

  • 相关阅读:
    随笔2
    随笔
    关于updateElement接口
    随笔1
    本地访问正常,服务器访问乱码 记录
    Redis (error) NOAUTH Authentication required.解决方法
    tomcat启动很慢 停留在 At least one JAR was scanned for TLDs yet contained no TLDs.
    微信公众号消息回复
    微信公众号 报token验证失败
    idea中web.xml报错 Servlet should have a mapping
  • 原文地址:https://www.cnblogs.com/linybo/p/13925526.html
Copyright © 2011-2022 走看看