网站内容的编辑和更新怎么做的,建站用wordpress 起飞了,WordPress支持邮箱登录,iis8出现在网站首页建造者模式又被成为生成器模式#xff0c;是一种使用频率比较低#xff0c;相对复杂的创建型模式#xff0c;在很多源码框架中可以看到建造者的使用场景#xff0c;稍后我们会在本文末尾展示几个框架的使用案例。 建造者模式所构造的对象通常是比较复杂而且庞大的#x… 建造者模式又被成为生成器模式是一种使用频率比较低相对复杂的创建型模式在很多源码框架中可以看到建造者的使用场景稍后我们会在本文末尾展示几个框架的使用案例。 建造者模式所构造的对象通常是比较复杂而且庞大的也是按照既定的构建顺序将对象中的各个属性组装起来。与工厂模式不同的是建造者模式主要目的是把繁琐的构建过程从产品类和工厂类中抽离出来进一步解耦最终实现用一套标准的制造工序制造出不同的产品。
1. 定义 建造者模式 的官方定义是将一个复杂对象的构建和表示分离使得同样的构建过程可以创建不同的表示。建造者模式一步一步地创建一个复杂的对象它允许用户通过指定复杂对象的类型和内容就可以构建它们用户不需要知道内部的构造细节。 官方的表达还是挺难理解的总体意思就是构建过程固定构建使用的每个组件都可以通过继承或者实现 呈现出多态的特性这依赖于抽象建造者接口和具体的建造者实现类两个组件来表示。 在建造者模式中通常包含4个角色
产品复杂的产品类建造者的最终产物构建过程相对复杂需要很多组件组装而成。抽象建造者建造者接口包含两个方便一个是构成产品的各个属性一个是各个属性的构建步骤方法。建造者实现建造者接口的实现类可以有多个对应不同的组件实现细节但是不会包含构建的顺序逻辑。指导者客户端依赖的创建产品的指导者类指导者类会通过建造者接口引入具体的建造者实现并且包含了具体的构建顺序。 2. 代码实现 建造者的实现逻辑想对复杂下面展示一个酒水制造的代码案例某个酒厂生产啤酒和红酒两类产品对应上述的四个角色代码实现如下
1. 产品
// 产品对象
public class Wine {// 用list封装制作工艺表示制作的顺序是固定的private ListString list new ArrayList();// 1.准备原材料public void setPrepareMaterial(String prepareMaterial) {list.add(prepareMaterial);}// 2.制作工艺public void setCraftsmanShip(String craftsmanShip) {list.add(craftsmanShip);}// 3.出厂包装public void setFactoryPackage(String factoryPackage) {list.add(factoryPackage);}Overridepublic String toString() {return Wine{ list list };}
}2. 抽象建造者
// 抽象的建造者
public abstract class AbstractBuilder {// 自定义产品Wine wine new Wine();// 设置原材料public abstract void setPrepareMaterial();// 设置制作工艺public abstract void setCraftsmanShip();// 设置出厂包装public abstract void setFactoryPackage();// 获取产品 - 注意这里是个钩子方法子类可以不实现public Wine getProduct() {return wine;}
}3. 建造者实现
// 啤酒建造者-具体的子类实现
public class BeerBuilder extends AbstractBuilder {Overridepublic void setPrepareMaterial() {wine.setPrepareMaterial(1.准备原材料小麦 豆子);}Overridepublic void setCraftsmanShip() {wine.setCraftsmanShip(2.制作工艺发酵 蒸馏);}Overridepublic void setFactoryPackage() {wine.setFactoryPackage(3.出厂包装易拉罐 纸箱);}
}// 葡萄酒制造者 - 具体的子类实现
public class GrapeBuilder extends AbstractBuilder{Overridepublic void setPrepareMaterial() {wine.setPrepareMaterial(1.准备原材料葡萄 酵母);}Overridepublic void setCraftsmanShip() {wine.setCraftsmanShip(2.制作工艺发酵 地下贮存);}Overridepublic void setFactoryPackage() {wine.setFactoryPackage(3.出厂包装玻璃瓶 木箱);}
}4. 指导者
// 指挥者 - 构造产品对象
public class Director {private AbstractBuilder abstractBuilder;public Director(AbstractBuilder abstractBuilder) {this.abstractBuilder abstractBuilder;}// 这里固定制造的工序按照固定步骤执行public Wine createProduct() {// 第一步设置原材料abstractBuilder.setPrepareMaterial();// 第二步设置制作工艺abstractBuilder.setCraftsmanShip();// 第三步设置出厂包装abstractBuilder.setFactoryPackage();// 第四步返回产品return abstractBuilder.getProduct();}
}客户端
// 客户端
public class Client {public static void main(String[] args) {// 啤酒制造Director beerDirector new Director(new BeerBuilder());Wine beer beerDirector.createProduct();System.out.println(beer);// 红酒制造Director grapeDirector new Director(new GrapeBuilder());Wine grape grapeDirector.createProduct();System.out.println(grape);}
}3. UML类图 对照上述的代码Demo我们来把这个案例的类图画出来对应如下
4. 简化 因为建造者是属于相对复杂的一种模式在实际的应用当中有很多种简化的写法比如可以忽略指导者类、建造者接口等等。下面是一种实现方式这种实现方式在很多源码中可以看到具体实现。 通常在产品类的构造函数参数超过4个而且这些参数中有一些是必填项考虑使用这种建造者模式。现在我们来构建一个电脑的产品对象。
// 电脑产品对象
public class Computer {private String cpu; // 必选private String ram; // 必选private String keyboard; // 可选private String mouse; // 可选private String display; // 可选
}这种bean类的属性设置有两种方式一个是构造函数入参一个是通过set()方法入参这两种方式都有些问题。构造函数入参当参数较多的时候类型相同的情况下属性的顺序容易混乱第二个中set()方式一个对象会支持在很多模块中设置因为类中的属性是可以分布设置的所以容易出现属性状态变化造成错误。 下面是一种简易的建造者实现方式在实际场景中可能属性的构建过程很复杂
建造者模式
// 电脑产品对象
public class Computer {private final String cpu; // 必选private final String ram; // 必选private final String keyboard; // 可选private final String mouse; // 可选private final String display; // 可选private Computer(Computer.Builder builder) {this.cpu builder.cpu;this.ram builder.ram;this.keyboard builder.keyboard;this.mouse builder.mouse;this.display builder.display;}public static Computer.Builder builder(String cpu, String ram) {return new Computer.Builder(cpu, ram);}public static class Builder {private String cpu; // 必选private String ram; // 必选private String keyboard; // 可选private String mouse; // 可选private String display; // 可选Builder(String cpu, String ram) {this.cpu cpu;this.ram ram;}public Builder cpu(String cpu) {this.cpu cpu;return this;}public Builder ram(String ram) {this.ram ram;return this;}public Builder keyboard(String keyboard) {this.keyboard keyboard;return this;}public Builder mouse(String mouse) {this.mouse mouse;return this;}public Builder display(String display) {this.display display;return this;}public Computer build() {return new Computer(this);}}Overridepublic String toString() {return Computer{ cpu cpu \ , ram ram \ , keyboard keyboard \ , mouse mouse \ , display display \ };}
}客户端实现
// 客户端
public class Client {public static void main(String[] args) {Computer computer Computer.builder(cpu, ram).cpu(cpu-1).mouse(mouse).display(display).build();System.out.println(computer);}
}5. 总结 建造者模式的核心在于如何一步一步地构建一个包含多个组成部件的完整对象使用相同的构建过程可以构建不同的产品。在软件开发中如果需要创建复杂对象并且系统系统具备良好的灵活性和扩展性可以考虑使用建造者模式。
首先建造者模式使得客户端和产品创建的过程解耦客户端可以不知道产品创建的内部细节构建过程固定的情况下构建的细节可以多变性这就可以很方便的增加不同的构造实现符合开闭原则将每个属性的构建过程分解在不同的方法中精细化管理高内聚才能低耦合符合单一职责。
6. 框架中的应用
StringBuilder和StringBufferSqlSessionBuilderLombok的Builder注解