“设计模式系列-Builder模式,工厂方法模式和抽象工厂模式”


建造者的模式

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

使用场景: 1.多个部件或零件,都可以装配到一个对象中,但产生的结果又不相同时。 2.当初始化一个对象特别复杂的时候,比如参数多,而且很多参数都有默认值。

s

它分为抽象建造者(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();
        }
    }

工厂方法模式

定义:定义一个用于创建对象的接口,让子类决定实例化哪个类。

s

任何需要生成复杂对象的地方,都可以使用工厂方法模式。用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建造者模式

工厂方法模式注重的是整体对象的创建方法,而建造者模式注重的是部件构建的过程,旨在通过一步一步地精确构造创建出一个复杂的对象。 我们举个简单例子来说明两者的差异,如要制造一个超人,如果使用工厂方法模式,直接产生出来的就是一个力大无穷、能够飞翔、内裤外穿的超人; 而如果使用建造者模式,则需要组装手、头、脚、躯干等部分,然后再把内裤外穿,于是一个超人就诞生了。

工厂方法模式创建的产品一般都是单一性质产品,如成年超人,都是一个模样,而建造者模式创建的则是一个复合产品,它由各个部件复合而成,部件不同产品对象当然不同。 这不是说工厂方法模式创建的对象简单,而是指它们的粒度大小不同。一般来说,工厂方法模式的对象粒度比较粗,建造者模式的产品对象粒度比较细。

两者的区别有了,那在具体的应用中,我们该如何选择呢? 是用工厂方法模式来创建对象,还是用建造者模式来创建对象,这完全取决于我们在做系统设计时的意图,如果需要详细关注一个产品部件的生产、安装步骤,则选择建造者,否则选择工厂方法模式。

抽象工厂模式

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类

s

    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(),然后两个实现类都要修改,想想看,这严重违反了开闭原则。



本作品由 Tony Zhang 创作,采用 CC BY-NC-SA 3.0 许可协议 进行许可。

Comments