zoukankan      html  css  js  c++  java
  • 设计模式---创建者模式

    一段很有趣的代码如下:
    HttpUrl url = new HttpUrl.Builder()
                    .scheme("http")
                    .host(host)
                    .port(port)
                    .encodedPath(uri)
                    .build();
    这种链式调用,可以使我们的代码看起来更加简洁易懂,这段代码最终是通过build来创建 HttpUrl对象
    上面这种创建对象的写法都是采用的builder模式
    建造者模式的定义为:将一个复杂对象的构建和它的表示分离开,使得同样的构建过程可以创建不同的表示。
    建造者模式一共有4个角色:
    1.抽象建造者(Builder)角色:该角色用于规范产品的各个组成部分,并进行抽象,一般独立于应用程序的逻辑。
    2.具体建造者(Concrete Builder)角色:该角色实现抽象建造者中定义的所有方法,并且返回一个组建好的产品实例。
    3.产品(Product)角色:该角色是建造者中的复杂对象,一个系统中会有多于一个的产品类,这些产品类并不一定有共同的接口,完全可以是不相关联的。
    4.导演者(Director)角色:该角色负责安排已有模块的顺序,然后告诉Builder开始建造。
    buidler模式的侧重点是在创建对象,也就是new对象方面。
    二、常见两种构建方式:
    1.多重载构造函数
    先举个例子:需求是这样 现在有个Person类,有name、age、location、job属性。这几个属性只有name是必须的,其余是可选的。ok,我们先来一个正常逻辑代码:
    public class Person {
      private final String name;
      private int age;
      private String location;
      private String job;
      public Person(String name) {
          this.name = name;
      }
      public Person(String name, int age) {
          this.name = name;
          this.age = age;
      }
      public Person(String name, int age, String location) {
          this.name = name;
          this.age = age;
          this.location = location;
      }
      public Person(String name, int age, String location, String job) {
          this.name = name;
          this.age = age;
          this.location = location;
          this.job = job;
      }
    }
    这种方式:简单!
    真的很简单,要什么参数 构造函数一目了然。
    但是,作为调用方,他在new对象的同时,要明白每个构造函数,否则一不小心把顺序填错了,岂不很尴尬。
    而且 这是只有四个参数,如果10几个个怎么办,是不是要10几个构造函数?
    缺点也很明确:
    参数多了不适用,不容易维护。
    
    2、setter方法构造:
    public class Person {
       private String name;
       private int age;
       private String location;
       private String job;
       public String getName() {
           return name;
       }
       public int getAge() {
           return age;
       }
       public void setAge(int age) {
           this.age = age;
       }
       public String getLocation() {
           return location;
       }
       public void setLocation(String location) {
           this.location = location;
       }
       public String getJob() {
           return job;
       }
       public void setJob(String job) {
           this.job = job;
       }
    }
    
    这种方式也是常见的构造方式。这种方式有一点比较好,容易理解,比如setName,就是给name赋值。
    但是缺点也显而易见:
    1 参数变量不是能final。
    2 对象状态不连续,必须在4次setter之后才能获取一个完整状态的对象。
    3 代码量偏多。同样的问题10个属性,我需要调用setXXX十几次。
    
    这里给大家解释一下什么是不完整状态的对象:
    这里创建对象明显是2个步骤:
    1、创建对象,2、赋值。
    这种方式创建对象,就有可能在第二步赋值时,返回对象,那么创建的对象就是不完整的对象。
    
    三、Builder模式如何调用
    public class Person {
       private final String name;
       private int age;
       private String location;
       private String job;
       public String getName() {
           return name;
       }
       public int getAge() {
           return age;
       }
       public String getLocation() {
           return location;
       }
       public String getJob() {
           return job;
       }
       Person(PersonBuilder personBuilder) {
           this.name = personBuilder.name;
           this.location = personBuilder.location;
           this.job = personBuilder.job;
           this.age = personBuilder.age;
       }
       public static class PersonBuilder {
           final String name;
           int age;
           String location;
           String job;
           PersonBuilder(String userName) {
               this.name = userName;
           }
           public PersonBuilder age(int age) {
               this.age = age;
               return this;
           }
           public PersonBuilder location(String location) {
               this.location = location;
               return this;
           }
           public PersonBuilder job(String job) {
               this.job = job;
               return this;
           }
           public Person builder() {
               return new Person(this);
           }
       }
    }
    
     Person person = new Person.PersonBuilder("cj")
                    .age(24)
                    .job("java")
                    .location("苏州")
                    .builder();
    
    可以看到变种的builder模式包括以下内容:
    1 一个静态内部类,静态内部类的参数和构建类一样。
    2 外部类只提供get方法方便查看,静态内部类提供set方法,赋值操作。
    3 静态内部类提供的setter操作,返回值是当前Builder本身。
    4 外部类的构造参数是静态内部类,使用静态内部类的变量赋值给外部类。
    5 最终提供builder返回外部类
    这种builder模式跟传统的builder模式确实是不太一样。但其实本质还是一样的,我们可以一一对应:
    产品(Product)角色::也就是创建一个类,声明其成员变量,相当与person类。
    抽象建造者角色:相当于静态内部类,复制产品定义的属性到静态内部类中,同时生成set方法。
    具体的建造者:也就是外部类提供的构造函数,将静态内部类的变量值赋值给外部类。
    导演角色:静态内部类中的builder方法。
    

      

  • 相关阅读:
    【leetcode】1324. Print Words Vertically
    【leetcode】1323. Maximum 69 Number
    【leetcode】1320. Minimum Distance to Type a Word Using Two Fingers
    【leetcode】1319. Number of Operations to Make Network Connected
    7系列GTX中的疑惑
    8b10b
    hB
    MATLAB实现最优低通滤波器的函数
    modelsim读写TXT文件
    ILA用法
  • 原文地址:https://www.cnblogs.com/ShouWangYiXin/p/13393319.html
Copyright © 2011-2022 走看看