关于android:Java-23种设计模式之构建者Builder模式

30次阅读

共计 8998 个字符,预计需要花费 23 分钟才能阅读完成。

Java 23 种设计模式之构建者 Builder 模式

一:定义
建造者模式:指的是将一个 简单对象的构建 与它的 示意 拆散,使得同样的构建过程能够创立不同的示意,这样的设计模式称为建造者模式。
它是将一个简单的对象合成为多个简略的对象,而后一步一步构建而成。它将变与不变相拆散,即产品的组成部分是不变的,但每一部分是能够灵便抉择的
二.Builder 模式的构造
1. 产品角色(Product): 它是蕴含多个组成部件的简单对象,由具体建造者来创立其各个零部件。
2. 形象建造者(Builder): 它是一个蕴含创立产品各个子部件的形象办法的接口,通常还蕴含一个返回产品的办法 getResult().
3. 具体的建造者(Concrete Builder): 实现 Builder 接口,实现简单产品的各个部件的具体创立办法
4. 指挥者(Director): 它调用建造者对象中的部件结构与拆卸办法实现简单对象的创立,在指挥中不波及具体产品的信息

聚合关系 :聚合关系是一种非凡的关联关系,聚合关系强调的是整体和局部的关系,其中局部能够脱离整体而存在。比方雁群和一只大雁的关系,就是聚合关系,大雁来到雁群还是能够独立存在的。
依赖关系 :依赖关系是一种很弱的关系,个别是指一个类应用另一个类,这里学生捡到钱交给警察叔叔,学生和警察叔叔就是一种依赖关系
泛化关系 :泛化关系在 Java 中也叫作继承关系,在 UML 中咱们用带空心三角形的直线来示意,咱们减少两个类,一个 ConcreteBuilder1 类,一个 ConcreteBuilder2 类,两个类均继承自 Builder 类
三:Builder 模式的实现
1. 咱们要建造一个产品 Product– 组装电脑
2. 形象的 Builder— 装 CPU, 内存条,硬盘等形象的步骤
3.Builder 的具体实现 ConcreteBuilder — 对上述形象步骤的实现,比方装 i5CPU、8G 内存条、1T 硬盘
4. 使用者 Director — 电脑装机人员
(1)产品的 Product:电脑

public class Computer {
    /*CPU*/
    private String CPU;
    /* 内存 */
    private String memory;
    /* 硬盘 */
    private String hardDisk;
    /* 键盘 */
    private String keyboard;
    /* 鼠标 */
    private String mouse;
// 配置内存
 
    public void setCPU(String CPU) {this.CPU = CPU;}

 
// 配置内存
    public void setMemory(String memory) {this.memory = memory;}

  // 配置硬盘

    public void setHardDisk(String hardDisk) {this.hardDisk = hardDisk;}

  
// 配置键盘
    public void setKeyboard(String keyboard) {this.keyboard = keyboard;}

  // 配置鼠标
    public void setMouse(String mouse) {this.mouse = mouse;}

    @Override
    public String toString() {
        return "Computer{" +
                "CPU='" + CPU + '\'' +
                ", memory='" + memory + '\'' +
                ", hardDisk='" + hardDisk + '\'' +
                ", keyboard='" + keyboard + '\'' +
                ", mouse='" + mouse + '\'' +
                '}';
    }
}

(2)形象的构建者 Builder 类通过接口实现,也能够通过抽象类


public interface ComputerConfigBuilder {
    /* 电脑组装个别都须要装置 CPU、内存条、硬盘、键盘鼠标等,咱们把这一装置过程给形象进去,也就是这里的 ComputerConfigBuilder,至于具体装置什么须要其实现类来实现,另外其中还定义了一个获取 Conputer 的办法。*/
    void setCPU();
    void setMemery();
    void setHardDisk();
    void setKeyboard();
    void setMouse();
    // 定义了一个获取产品 Computer 的办法返回的 computer 对象
    Computer getComputer();}

应用抽象类能够这一应用

// 这里须要理解抽象类和接口的区别
public abstract class ComputerConfigBuilder1 {public abstract void setCPU();
    public abstract   void setMemery();
    public abstract  void setHardDisk();
    public abstract void setKeyboard();
    public abstract void setMouse();
    // 定义了一个获取产品 Computer 的办法返回的 computer 对象
    public abstract Computer getComputer();}

(3)创立一个低配版的套餐 LowConfigBuilder,让其实现 ComputerConfigBuilder

public class LowConfigBuilder implements ComputerConfigBuilder {
    // 产品类 Computer 类
    private Computer computer;

    public LowConfigBuilder() {
        // 构造方法中创立产品类
        this.computer = new Computer();}

    @Override
    public void setCPU() {computer.setCPU("i5");

    }

    @Override
    public void setMemery() {computer.setMemory("8G");

    }

    @Override
    public void setHardDisk() {computer.setHardDisk("500G");

    }

    @Override
    public void setKeyboard() {computer.setKeyboard("薄膜键盘");

    }

    @Override
    public void setMouse() {computer.setMouse("有线鼠标");

    }
/** 具体实现类返回产品 */
    @Override
    public Computer getComputer() {return computer;}
}

高配的组装类

public class HighConfigBuider  implements ComputerConfigBuilder{
    private Computer mComputer;

    public HighConfigBuider(){this.mComputer = new Computer();
    }
    @Override
    public void setCPU() {mComputer.setCPU("i7");
    }

    @Override
    public void setMemery() {mComputer.setMemory("16G");
    }

    @Override
    public void setHardDisk() {mComputer.setHardDisk("1T");
    }

    @Override
    public void setKeyboard() {mComputer.setKeyboard("机械键盘");
    }

    @Override
    public void setMouse() {mComputer.setMouse("无线鼠标");
    }

    @Override
    public Computer getComputer() {return mComputer;}
}

(4)须要一个拆卸人员 Director

public class Director {
    private ComputerConfigBuilder mBuilder;
    // 这里 setBuilder 是拿到具体的建造者对象
    public void setBuilder(ComputerConfigBuilder builder){this.mBuilder=builder;}
    // 拆卸人员 director 通过建造者拆卸具体的产品过程
    public void createComputer(){mBuilder.setCPU();
        mBuilder.setMemery();
        mBuilder.setHardDisk();
        mBuilder.setKeyboard();
        mBuilder.setMouse();}
    // 拆卸人员拆卸好产品电脑返回
    public Computer getComputer(){return mBuilder.getComputer();
    }
}

(5)调用

public class ThirdTeenActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third_teen);
        Director director=new Director();// 创立装机人员
        director.setBuilder(new LowConfigBuilder());// 通知装机人员的电脑配置,这里是低配版
        director.createComputer();// 装机人员开始组装
       Computer computer= director.getComputer();// 从装机人员获取组装好的电脑
        System.out.println("低配电脑配置:"+computer.toString());
        Log.d("aa",computer.toString());
        
        Director director1=new Director();
        director1.setBuilder(new HighConfigBuider());// 高配组装
        director1.createComputer();
        Computer computer1=director1.getComputer();
        System.out.println("高配电脑配置:"+computer1.toString());
        Log.d("aa",computer1.toString());

    }
}

// 后果
System.out: 低配电脑配置:Computer{CPU='i5', memory='8G', hardDisk='500G', keyboard='薄膜键盘', mouse='有线鼠标'}
aa: Computer{CPU='i5', memory='8G', hardDisk='500G', keyboard='薄膜键盘', mouse='有线鼠标'}
System.out: 高配电脑配置:Computer{CPU='i7', memory='16G', hardDisk='1T', keyboard='机械键盘', mouse='无线鼠标'}
aa: Computer{CPU='i7', memory='16G', hardDisk='1T', keyboard='机械键盘', mouse='无线鼠标'}

四:变种 Builder 模式
须要创立一个不可变的 Person 对象,这个 Person 能够领有以下几个属性:名字、性别、年龄、职业、车、鞋子、衣服、钱、房子。其中名字和性别是必须有的

public class Person {
    /* 名字(必须)*/
    private final String name;
    /* 性别(必须)*/
    private final String gender;
    /* 年龄(非必须)*/
    private final String age;
    /* 鞋子(非必须)*/
    private final String shoes;
    /* 衣服(非必须)*/
    private final String clothes;
    /* 钱(非必须)*/
    private final String money;
    /* 房子(非必须)*/
    private final String house;
    /* 汽车(非必须)*/
    private final String car;
    /* 职业(非必须)*/
    private final String career;

    private Person(Builder builder) {
        this.name = builder.name;
        this.gender = builder.gender;
        this.age = builder.age;
        this.shoes = builder.shoes;
        this.clothes = builder.clothes;
        this.money = builder.money;
        this.house = builder.house;
        this.car = builder.car;
        this.career = builder.career;
    }
    // 动态外部类
    public static class Builder{
        private final String name;
        private final String gender;
        private String age;
        private String shoes;
        private String clothes;
        private String money;
        private String house;
        private String car;
        private String career;
        public Builder(String name,String gender) {
            this.name = name;
            this.gender = gender;
        }
        public Builder age(String age) {
            this.age = age;
            return this;
        }

        public Builder car(String car) {
            this.car = car;
            return this;
        }

        public Builder shoes(String shoes) {
            this.shoes = shoes;
            return this;
        }

        public Builder clothes(String clothes) {
            this.clothes = clothes;
            return this;
        }

        public Builder money(String money) {
            this.money = money;
            return this;
        }

        public Builder house(String house) {
            this.house = house;
            return this;
        }
        public Builder career(String career) {
            this.career = career;
            return this;
        }

        // 创立一个 Person 类的对象
        public Person build(){return new Person(this);
        }
    }
// 输入对象
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", age='" + age + '\'' +
                ", shoes='" + shoes + '\'' +
                ", clothes='" + clothes + '\'' +
                ", money='" + money + '\'' +
                ", house='" + house + '\'' +
                ", car='" + car + '\'' +
                ", career='" + career + '\'' +
                '}';
    }
}

// 应用
 Person person=new Person.Builder("Rocky", "男").age("18").build();
        System.out.println("person"+person);
        
        // 后果
        System.out: personPerson{name='Rocky', gender='男', age='18', shoes='null', clothes='null', money='null', house='null', car='null', career='null'}
        

这里应用 Person 相似于产品,Builder 外部类等价于构建者
因为这个 Person 对象是不可变的,所以毫无疑问咱们给他的所有属性都加了 final 润饰,当然如果没有不可变的需要也是能够不加的,
而后在 Person 类中定义一个外部类 Builder,这个 Builder 外部类中的属性要和 Person 中的雷同,并且必须有的属性要用 final 润饰,避免这些属性没有被赋值,其余非必须的属性不能用 final,因为如果加了 final,就必须对其进行初始化,这样这些非必须的属性又变成必须的。
而后外部类中定义了一个构造方法,传入必须有的属性。其余非必须的属性都通过办法设置,每个办法都返回 Builder 对象本身。
最初定义了一个 build 办法,将 Builder 对象传入 Person 的公有构造方法,最终返回一个对象。
五:Android 中网络申请 OKHttp3 创立申请信息的 Request 的源码
这里使用的变种的 Builder 构建者模型

因为这个 Request 对象是不可变的,所有属性都加了 final 润饰
public final class Request {
// 这里定义的属性是不可更改的
  final HttpUrl url;
  final String method;
  final Headers headers;
  final @Nullable RequestBody body;
  final Object tag;

  private volatile CacheControl cacheControl; // Lazily initialized.

  Request(Builder builder) {
    this.url = builder.url;
    this.method = builder.method;
    this.headers = builder.headers.build();
    this.body = builder.body;
    this.tag = builder.tag != null ? builder.tag : this;
  }
  // 这里配置的 url 是为了内部获取 url 属性值

  public HttpUrl url() {return url;}

  public String method() {return method;}

  public Headers headers() {return headers;}

  public String header(String name) {return headers.get(name);
  }

  public List<String> headers(String name) {return headers.values(name);
  }

  public @Nullable RequestBody body() {return body;}

  public Object tag() {return tag;}

  public Builder newBuilder() {return new Builder(this);
  }
  
// 打印申请的数据
  @Override public String toString() {
    return "Request{method="
        + method
        + ", url="
        + url
        + ", tag="
        + (tag != this ? tag : null)
        + '}';
  }
   public static class Builder {
    HttpUrl url;//url 链接
    String method;// 申请形式 get,post,head 等
    Headers.Builder headers;// 申请头
    RequestBody body;// 申请体
    Object tag;
// 默认的申请形式是 get 申请
    public Builder() {
      this.method = "GET";
      this.headers = new Headers.Builder();}

    Builder(Request request) {
      this.url = request.url;
      this.method = request.method;
      this.body = request.body;
      this.tag = request.tag;
      this.headers = request.headers.newBuilder();}
// 构建的 url
    public Builder url(HttpUrl url) {if (url == null) throw new NullPointerException("url == null");
      this.url = url;
      return this;
    }。。。。。// 构建的申请头
     public Builder header(String name, String value) {headers.set(name, value);
      return this;
    }
    //get 申请
     public Builder get() {return method("GET", null);
    }
//head 申请
    public Builder head() {return method("HEAD", null);
    }
//post 申请
    public Builder post(RequestBody body) {return method("POST", body);
    }
    // 这里 build 是创立 Request 对象,url 是必须有的
     public Request build() {if (url == null) throw new IllegalStateException("url == null");
      return new Request(this);
    }
    }
    }
    
    // 应用
     Request mRequest=new Request.Builder()
                .get()
                .url("https://www.baidu.com")
                .build();
    

长处:我能够不用晓得你的外部结构是怎么的,我能够间接应用 Builder 建造本人须要的客户端;代码清晰,易保护,易扩大; 将结构和示意拆散,升高耦合
毛病:代码也可能不清晰,不易保护(怎么说:比方你的客户端实现了很多接口,当你每当批改接口的时候,每次都要对应批改你的客户端);应用不失当耗费内存

END: 达到目标的惟一力量就是我的保持精力。

正文完
 0