zoukankan      html  css  js  c++  java
  • 建造者模式

    一、定义

    建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
    工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的 Test 结合起来得到的。

     建造者模式通常包括下几个角色: 
    1. builder(抽象建造者):给出一个抽象结论,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的对象部件的创建。 
    2. ConcreteBuilder(具体建造者):实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。在构造过程完成后,提供产品的实例。 
    3. Director(指导者):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。 
    4. Product(产品类):要创建的复杂对象。

    二、建造者模式的应用场景

    拿车来说车的建造过程,包括造轮子,造发动机和造车身结构,这些生产顺序和装配顺序是可调的

    /**
     * 产品类
     */
    @Data
    public class Car {
        private String wheel;
        private String skeleton;
        private String engine;
    }
    /**
     *  抽象建造者
     */
    public interface ICarBuilder {
        public void buildWheel();
        public void buildSkeleton();
        public void buildEngine();
    
        Car buildCar();
    }
    /**
     * 具体建造者
     */
    public class ConcreteBuilder implements ICarBuilder
    {
        Car car;
    
        public ConcreteBuilder()
        {
            car = new Car();
        }
    
        @Override
        public void buildWheel()
        {
            car.setWheel("轮子");
        }
    
        @Override
        public void buildSkeleton()
        {
            car.setSkeleton("车身结构");
        }
    
        @Override
        public void buildEngine()
        {
            car.setEngine("发动机");
        }
    
        @Override
        public Car buildCar()
        {
            return this.car;
        }
    
    
    }
    /**
     * 指导者
     */
    public class CarDirector {
        public Car constructCar(ICarBuilder builder) {
            builder.buildEngine();
            builder.buildSkeleton();
            builder.buildWheel();
            return builder.buildCar();
        }
        }
    public class MainTest {
        public static void main(String[] args)
        {
            CarDirector director = new CarDirector();
            Car car = director.constructCar(new ConcreteBuilder());
            System.out.println(car.getWheel());
            System.out.println(car.getEngine());
            System.out.println(car.getSkeleton());
        }
    }

    三、适用场景

    建造者模式适用于一个具有较多的零件的复杂产品的创建过程,由于需求的变化,组成这个复杂产品的各个零件经常发送变化,但是他们的组合方式却相对稳定。

    ​ 建造者模式适用于以下几种场景:

    1、相同的方法,不同的执行顺序,产生不同的结果时。

    2、多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同

    3、产品类非常复杂,或者产品类中的调用顺序不同产生不同的作用,

    4、当初始化一个对象特别复杂,参数多,而且很多参数都有默认值时。

    四、建造者的链式写法

    /**
     * 具体建造者
     */
    public class ConcreteBuilder {
    
        private  Car car=new Car();
    
        public ConcreteBuilder addWheel(String wheel){
            car.setWheel(wheel);
            return this;
        }
        public ConcreteBuilder addSkeleton(String skeleton){
            car.setSkeleton(skeleton);
            return this;
        }
        public ConcreteBuilder addEngine(String engine){
            car.setEngine(engine);
            return this;
        }
    
        public void buildWheel() {
    
        }
    
    
        public void buildSkeleton() {
    
        }
    
    
        public void buildEngine() {
    
        }
    
    
        public Car buildCar() {
            return this.car;
        }
    
        @Data
        public class Car {
            private String wheel;
            private String skeleton;
            private String engine;
        }
    
    
    
    
    }
    public class MainTest {
        public static void main(String[] args)
        {
            ConcreteBuilder concreteBuilder=new ConcreteBuilder()
                    .addWheel("轮子")
                    .addEngine("发动机")
                    .addSkeleton("车身结构");
            System.out.println(concreteBuilder.buildCar());
        }
    }
    开源框架JPA的SQL构造模式。在构造SQL查询条件的时候,需要根据不同的条件来拼接SQL字符串。如果查询条件复杂的时候,SQL拼接的过程也会变得非常复杂,从而给我们的代码维护带来非常大的困难。因此,所以如果有的大佬在写自己封装的sql框架时也会用到这里面的思想

    五、建造者模式在源码中的体现

    看JDK的StringBuilder,它提供append()方法,给我们开放构造步骤,最后调用toString()方法就可以获得一个构造好的完整字符串,源码如下:

    public final class StringBuilder
        extends AbstractStringBuilder
        implements java.io.Serializable, CharSequence
    {
        public StringBuilder append(StringBuffer sb) {
            super.append(sb);
            return this;
        }
    }

    在MyBatis中也有体现,比如CacheBuilder类。同样在 MyBatis 中,比如 SqlSessionFactoryBuilder 通过调用 build()方法获得的是一个SqlSessionFactory 类。

    当然,在 Spring中自然也少不了,比如 BeanDefinitionBuilder 通过调用getBeanDefinition()方法获得一个BeanDefinition对象。

    六、总结

    建造者模式的优点:

    1、封装性好,创建和使用分离;

    2、扩展性好,建造类之间独立、一定程度上解耦。

    建造者模式的缺点:

    1、产生多余的Builder对象;

    2、产品内部发生变化,建造者都要修改,成本较大。

    建造者模式和工厂模式的区别

    1、建造者模式更加注重方法的调用顺序,工厂模式注重于创建对象。

    2、创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的都一样。

    3、关注重点不一样,工厂模式模式只需要把对象创建出来就可以了,而建造者模式中不仅要创建出这个对象,还要知道这个对象由哪些部件组成。

    4、建造者模式根据建造过程中的顺序不一样,最终的对象部件组成也不一样。可以理解为工厂创建过程是静态的,构建者模式创建过程经过外放而变成动态的。

    git源码:https://github.com/ljx958720/design_patterns.git
     
    这短短的一生我们最终都会失去,不妨大胆一点,爱一个人,攀一座山,追一个梦
  • 相关阅读:
    Study Plan The Twelfth Day
    Study Plan The Fifteenth Day
    Study Plan The Seventeenth Day
    Study Plan The Tenth Day
    Study Plan The Eighth Day
    Study Plan The Eleventh Day
    Study Plan The Sixteenth Day
    Study Plan The Thirteenth Day
    Study Plan The Fourteenth Day
    Study Plan The Ninth Day
  • 原文地址:https://www.cnblogs.com/xing1/p/14564368.html
Copyright © 2011-2022 走看看