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

建造者的模式

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

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

builder.png

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

工厂方法模式

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

factory.png

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

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

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

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

抽象工厂模式

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

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 设计模式汇总 一、基础知识 1. 设计模式概述 定义:设计模式(Design Pattern)是一套被反复使用、多...
    MinoyJet阅读 9,375评论 1 15
  • 没有人买车会只买一个轮胎或者方向盘,大家买的都是一辆包含轮胎、方向盘和发动机等多个部件的完整汽车。如何将这些部件组...
    justCode_阅读 5,869评论 1 6
  • 创建型模式 抽象工厂模式(abstract facroty) 3.1模式动机 在工厂方法模式中具体工厂负责生产具体...
    僚机KK阅读 4,059评论 0 2
  • 文/小哲小诗 走过树林 那苍翠的松林 一片连成一片 近近的触动你的神经 远远的感受生命的情怀 青色的树海 你边走边...
    小哲小诗阅读 3,138评论 2 0
  • 老城中,藏于繁华之后的那些蜿蜒交错的胡同,不仅仅是这座城市的脉络,交通的衢道,更是老北京人生活在这的纹理。灰墙灰瓦...
    小满生活公会阅读 3,777评论 0 0