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

    建造者模式定义:

    讲一个复杂对象的构造与其表示进行分离,使同样的构建过程可以创建不同的表示。其实就是将一个复杂对象分解为多个简单的对象,然后一步一步构建而成,将变与不变进行分析,也就是说产品的组成部分不变,但每一部分都可以进行灵活选择。

    其优点:

    • 每个具体的建造着相对独立,这样有利于系统扩展
    • 客户端不必知道产品内部的组成细节,便于控制细节风险

    其缺点:

    • 产品的组成部分必须相同,使用范围会受限
    • 如果产品内部变化较为复杂,这样会增加很多的建造着类。

    建造者模式注重的就是零部件的组装过程。

    结构:

    • 产品角色(Product):包含多个组成组件的复杂对象,有具体的建造者来创建其各个部件
    • 抽象建造者(Builder):一个包含创建产品各个自组件的抽象方法的接口,通常包含一个返回复杂产品的方法getResult()
    • 具体建造者(Concrete Builder):实现Builder接口,完成复杂产品的各个部件的具体创建方法
    • 指挥者(Director):调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

    上述图就是鉴照着模式的结构图,看一下代码的具体实现

    产品角色:包含多个组成部件

    package builder.module;
    
    /**
     * 产品角色
     */
    public class Product {
    
        private String part1;
    
        private String part2;
    
        private String part3;
    
        public void setPart1(String part1) {
            this.part1 = part1;
        }
    
        public void setPart2(String part2) {
            this.part2 = part2;
        }
    
        public void setPart3(String part3) {
            this.part3 = part3;
        }
    
        /**
         * 显示产品特性
         */
        public void show(){
            System.out.println(part1);
            System.out.println(part2);
            System.out.println(part3);
        }
    }

    抽象构建者:包含创建产品各个不见得抽象方法

    package builder.module;
    
    /**
     * 抽象构建者
     */
    public abstract class Builder {
    
        protected Product product = new Product();
    
        public abstract void buildPart1();
    
        public abstract void buildPart2();
    
        public abstract void buildPart3();
    
        /**
         * 返回产品对象
         *
         * @return 产品对象
         */
        public Product getResult() {
            return product;
        }
    }

    具体建造者:实现抽象建造着的方法,完成复杂对象的创建

    /**
     * 具体建造者  需要实现抽象建造着接口
     */
    public class ConcreteBuilder extends Builder{
        @Override
        public void buildPart1() {
            product.setPart1("建造 part1");
        }
    
        @Override
        public void buildPart2() {
            product.setPart2("建造 part2");
        }
    
        @Override
        public void buildPart3() {
            product.setPart3("建造 part3");
        }
    }

    指挥者:调用建造着中的方法完成复杂对象的创建

    package builder.module;
    
    /**
     * 指挥者
     */
    public class Director {
    
        private Builder builder;
    
        public Director(Builder builder){
            this.builder = builder;
        }
    
        /**
         * 产品构建以及组装方法
         * @return 完成构建的产品
         */
        public Product construct(){
            builder.buildPart1();
            builder.buildPart2();
            builder.buildPart3();
            return builder.getResult();
        }
    }

    客户端:客户端根据需求选定指定指定建造着

    package builder.module;
    
    public class Client {
        public static void main(String[] args) {
            // 使用具体的建造者
            Builder builder = new ConcreteBuilder();
            // 指挥者实例话,指定具体的建造着
            Director director = new Director(builder);
            // 通过指挥者根据对应的具体构建者创建产品
            Product product = director.construct();
            // 展示产品
            product.show();
        }
    }

     建造者模式通常的应用场景:

    创建的对象比较复杂,可能会有多个部件构成,各个部件面临着复杂的变化,但组成部分的建造顺序是稳定的

    创建复杂对象的算法独立于该对象的组成部分以及他们的装配方式,也就是说产品的构建过程和最终的表示是相对独立的。

    接下来搞个简单的demo:

    比如所有的车的工序都是一样的只需要轮子,logo,价格,那么做一个汽车模型Car,这个就是产品,接下来抽象一个工厂Factory,这个就是抽象建造着,然后实现比亚迪工厂BYDFactory,宝马工厂BMWFactory,特斯拉工厂TESLAFactory,这个就是具体建造着,一个4s店的代理商Agent,这个就是指挥者,然后客户就可以科举需求来购买指定的汽车

    产品Car

    package builder.demo;
    
    public class Car {
    
        private String wheel;
    
        private String logo;
    
        private String price;
    
        public void setWheel(String wheel) {
            this.wheel = wheel;
        }
    
        public void setLogo(String logo) {
            this.logo = logo;
        }
    
        public void setPrice(String price) {
            this.price = price;
        }
    
        public void show() {
            System.out.println("我是:" + logo + ",有" + wheel + "个轮子,我的售价" + price + "万元");
        }
    }

    抽象建造者Factory

    package builder.demo;
    
    /**
     * 抽象工厂
     */
    public abstract class Factory {
    
        // 创建产品对象
        protected Car car = new Car();
    
        public abstract void buildWheel();
    
        public abstract void buildLogo();
    
        public abstract void buildPrice();
    
        /**
         * 返回产品对象
         * @return 汽车产品
         */
        public Car getResult(){
            return car;
        }
    }

    具体建造者BMWFactory

    package builder.demo;
    
    /**
     * 宝马工厂
     */
    public class BMWFactory extends Factory {
        @Override
        public void buildWheel() {
            car.setWheel("4");
        }
    
        @Override
        public void buildLogo() {
            car.setLogo("BMW");
        }
    
        @Override
        public void buildPrice() {
            car.setPrice("40");
        }
    }

    剩下两个具体建造者类似

    指挥者Agent

    package builder.demo;
    
    /**
     * 4s销售点
     */
    public class Agent {
        private Factory factory;
    
        public Agent(Factory factory){
            this.factory = factory;
        }
    
        public Car construct(){
            factory.buildWheel();
            factory.buildLogo();
            factory.buildPrice();
            return factory.getResult();
        }
    }

    客户端

    package builder.demo;
    
    /**
     * 客户
     */
    public class Client {
    
        public static void main(String[] args) {
            Factory factory;
            // 通过指定的厂商获取具体工厂实例
            factory = (Factory) Util.getObject("BMWFactory");
            // 获取经销商实例
            Agent agent = new Agent(factory);
            // 经销商订货
            Car car = agent.construct();
            // 展示
            car.show();
        }
    }

    一个小工具类,就是通过类名实例化类

    package builder.demo;
    
    public class Util {
    
        public static Object getObject(String name){
            String cName = "builder.demo.." + name;
            System.out.println("新类名:"+cName);
            Class<?> c = null;
            try {
                // 根据名称获取类
                c = Class.forName(cName);
                // 调用该类的无参构造方法并获取实例
                return c.getDeclaredConstructor().newInstance();
            } catch (Exception e) {
                // 异常
                e.printStackTrace();
                return c;
            }
        }
    }

    源码地址:https://github.com/yang-shixiong/design/tree/master/src/builder

    适用场景:

    • 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
    • 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。
  • 相关阅读:
    中值定理
    poj 3984 迷宫问题 bfs
    android 处理网络状态——无网,2g,3g,wifi,ethernet,other
    POJ 1273 || HDU 1532 Drainage Ditches (最大流模型)
    Android硬件加速
    Android的横竖屏切换
    滑雪_poj_1088(记忆化搜索).java
    Rank of Tetris(hdu1811拓扑排序+并查集)
    git在windows下clone、pull或者push内存溢出的解决办法
    数据库中DDL、DML、DCL和TCP概念
  • 原文地址:https://www.cnblogs.com/yangshixiong/p/12566510.html
Copyright © 2011-2022 走看看