建造者的模式
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
使用场景:
1.多个部件或零件,都可以装配到一个对象中,但产生的结果又不相同时。
2.当初始化一个对象特别复杂的时候,比如参数多,而且很多参数都有默认值。
它分为抽象建造者(Builder)角色、具体建造者(ConcreteBuilder)角色、导演者(Director)角色、产品(Product)角色四个角色。
抽象建造者(Builder)角色:给 出一个抽象接口,以规范产品对象的各个组成成分的建造。
具体建造者(ConcreteBuilder)角色:要完成的任务包括:1.实现抽象建造者Builder所声明的接口,给出一步一步地完成创建产品实例的操作。2.在建造过程完成后,提供产品的实例。
导演者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。
产品(Product)角色:产品便是建造中的复杂对象。
public interface Builder {
public Builder setName(String name);
public Builder setSex(boolean sex);
public Builder setAge(int age);
public Person create();
}
public class ConcreteBuilder implements Builder {
private String name;
private boolean sex;
private int age;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setSex(boolean sex) {
this.sex = sex;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Person create() {
return new Person(name, sex, age);
}
}
public class Director {
private Builder builder;
public Director(Builder builder){
this.builder = builder;
}
public void construct(String name, boolean sex, int age) {
builder.setName(name);
builder.setSex(sex);
builder.setAge(age);
}
}
public class Test {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director pcDirector = new Director(builder);
pcDirector.construct("zhangtao", true, 23);
Person person = builder.create();
}
}
工厂方法模式
定义:定义一个用于创建对象的接口,让子类决定实例化哪个类。
任何需要生成复杂对象的地方,都可以使用工厂方法模式。用new就能创建的对象不需要使用工厂模式,因为使用工厂模式就要增加一个工厂类,增加了系统复杂度。
关于工厂方法模式的实现
public abstract class Product {
public abstract void method();
}
public class ConcreteProductA extends Product {
@Override
public void method() {
System.out.println("产品A");
}
}
public abstract class Factory {
public abstract Product createProduct();
}
public class ConcreteFactory extends Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
public class Test {
public static void main(String[] args) {
Factory factory = new ConcreteFactory();
Product product = factory.createProduct();
product.method();
}
}
当确定工厂类只有一个的时候,简单工厂模式
public class Factory{
public static Product createProduct(){
return new ConcreteProductA();
}
}
工厂方法模式VS建造者模式
工厂方法模式注重的是整体对象的创建方法,而建造者模式注重的是部件构建的过程,旨在通过一步一步地精确构造创建出一个复杂的对象。
我们举个简单例子来说明两者的差异,如要制造一个超人,如果使用工厂方法模式,直接产生出来的就是一个力大无穷、能够飞翔、内裤外穿的超人;
而如果使用建造者模式,则需要组装手、头、脚、躯干等部分,然后再把内裤外穿,于是一个超人就诞生了。
工厂方法模式创建的产品一般都是单一性质产品,如成年超人,都是一个模样,而建造者模式创建的则是一个复合产品,它由各个部件复合而成,部件不同产品对象当然不同。
这不是说工厂方法模式创建的对象简单,而是指它们的粒度大小不同。一般来说,工厂方法模式的对象粒度比较粗,建造者模式的产品对象粒度比较细。
两者的区别有了,那在具体的应用中,我们该如何选择呢?
是用工厂方法模式来创建对象,还是用建造者模式来创建对象,这完全取决于我们在做系统设计时的意图,如果需要详细关注一个产品部件的生产、安装步骤,则选择建造者,否则选择工厂方法模式。
抽象工厂模式
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类
public abstract class AbstractProductA {
//每个产品共有的方法
public void shareMethod(){
}
//每个产品相同方法,不同实现
public abstract void doSomething();
}
public class ProductA1 extends AbstractProductA {
public void doSomething() {
System.out.println("产品A1的实现方法");
}
}
public class ProductA2 extends AbstractProductA {
public void doSomething() {
System.out.println("产品A2的实现方法");
}
}
//抽象工厂类
public abstract class AbstractCreator {
//创建A产品家族
public abstract AbstractProductA createProductA();
//创建B产品家族
public abstract AbstractProductB createProductB();
}
public class Creator1 extends AbstractCreator {
//只生产产品等级为1的A产品
public AbstractProductA createProductA() {
return new ProductA1();
}
//只生产产品等级为1的B产品
public AbstractProductB createProductB() {
return new ProductB1();
}
}
public class Creator2 extends AbstractCreator {
//只生产产品等级为2的A产品
public AbstractProductA createProductA() {
return new ProductA2();
}
//只生产产品等级为2的B产品
public AbstractProductB createProductB() {
return new ProductB2();
}
}
public class Test {
public static void main(String[] args) {
//定义出两个工厂
AbstractCreator creator1 = new Creator1();
AbstractCreator creator2 = new Creator2();
//产生A1对象
AbstractProductA a1 = creator1.createProductA();
//产生A2对象
AbstractProductA a2 = creator2.createProductA();
//产生B1对象
AbstractProductB b1 = creator1.createProductB();
//产生B2对象
AbstractProductB b2 = creator2.createProductB();
}
}
抽象工厂模式的使用场景定义非常简单:一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。
通过工厂类,只要知道工厂类是谁,我就能创建出一个需要的对象
注意事项:
在抽象工厂模式的缺点中,我们提到抽象工厂模式的产品族扩展比较困难,但是一定要清楚,是产品族扩展困难,而不是产品等级。
在该模式下,产品等级是非常容易扩展的,增加一个产品等级,只要增加一个工厂类负责新增加出来的产品生产任务即可。
也就是说横向扩展容易,纵向扩展困难。
抽象类AbstractCreator要增加一个方法createProductC(),然后两个实现类都要修改,想想看,这严重违反了开闭原则。