23种设计模式(三)-对象创建

  • Factory Method 工厂方法

模式定义:
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。

组件:
抽象工厂(AbstractFactory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

类图.png

package com.lillcol.designmodel;

/**
 * @author lillcol
 * 2019/6/16-21:36
 */
public class FactoryMethod {
    public static void main(String[] args) {
        ConcreteFactory1 concreteFactory1 = new ConcreteFactory1();
        Product product = concreteFactory1.newProduct();
        product.show();
        System.out.println("-------------------------------------------");
        ConcreteFactory2 concreteFactory2 = new ConcreteFactory2();
        Product product2 = concreteFactory2.newProduct();
        product2.show();
    }
}

abstract class Product {//定义了产品的规范,描述了产品的主要特性和功能

    abstract void show();
}

class ConcreteProductA extends Product { //具体产品ProductA

    @Override
    void show() {
        System.out.println("ConcreteProductA");
    }
}

class ConcreteProductB extends Product { //具体产品ProductB

    @Override
    void show() {
        System.out.println("ConcreteProductB");
    }
}

abstract class AbstractFactory{ //提供了创建产品的抽象
    abstract Product newProduct();
}

class ConcreteFactory1 extends AbstractFactory{ //实现抽象工厂中的抽象方法,完成具体产品的创建。

    @Override
    Product newProduct() {
        return  new ConcreteProductA();
    }
}

class ConcreteFactory2 extends AbstractFactory{//实现抽象工厂中的抽象方法,完成具体产品的创建。

    @Override
    Product newProduct() {
        return  new ConcreteProductB();
    }
}
//输出结果:
ConcreteProductA
-------------------------------------------
ConcreteProductB

工厂方法模式的优点:
用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

工厂方法模式的缺点:
每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

  • AbstractFactory 抽象工厂

模式定义:
定义一个接口,让该借口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

使用抽象工厂模式条件:
系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
系统一次只可能消费其中某一族产品,即同族的产品一起使用。

组件:
抽象工厂(AbstractFactory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
具体工厂(ConcreteFactory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。

类图.png

package com.lillcol.designmodel;

/**
 * @author lillcol
 * 2019/6/16-22:38
 */
public class AbstractFactory {
    public static void main(String[] args) {
        ConcreteFactory1 concreteFactory1 = new ConcreteFactory1();
        concreteFactory1.newProduct1().show();
        concreteFactory1.newProduct2().show();
        System.out.println("-----------------------------------------");
        ConcreteFactory2 concreteFactory2 = new ConcreteFactory2();
        concreteFactory2.newProduct1().show();
        concreteFactory2.newProduct2().show();
    }
}
//中国 飞机:J20  航母:辽宁舰
//美国 飞机:F22  航母:福特级航母

abstract class Product1 {  //飞机
    abstract void show();
}

class ConcreteProduct11 extends Product1 {//中国飞机

    @Override
    void show() {
        System.out.println("中国 飞机:J20");
    }
}

class ConcreteProduct12 extends Product1 {//美国飞机:F22

    @Override
    void show() {
        System.out.println("美国 飞机:F22 ");
    }
}

abstract class Product2 {  //航母
    abstract void show();
}

class ConcreteProduct21 extends Product2 {//中国 航母:辽宁舰

    @Override
    void show() {
        System.out.println("中国 航母:辽宁舰");
    }
}

class ConcreteProduct22 extends Product2 {//美国 航母:福特级航母

    @Override
    void show() {
        System.out.println("美国 航母:福特级航母 ");
    }
}

abstract class Factory {
    abstract Product1 newProduct1();

    abstract Product2 newProduct2();
}
class ConcreteFactory1 extends Factory {//中国
    @Override
    Product1 newProduct1() {
        return new ConcreteProduct11();
    }

    @Override
    Product2 newProduct2() {
        return new ConcreteProduct21();
    }

}

class ConcreteFactory2 extends Factory {//美国
    @Override
    Product1 newProduct1() {
        return new ConcreteProduct12();
    }

    @Override
    Product2 newProduct2() {
        return new ConcreteProduct22();
    }

}
//输出结果:
中国 飞机:J20
中国 航母:辽宁舰
-----------------------------------------
美国 飞机:F22 
美国 航母:福特级航母 

抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下:
可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
当增加一个新的产品族时不需要修改原代码,满足开闭原则。

抽象工厂模式缺点:
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

  • Prototype 原型模式
    模式定义:
    使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象

原型模式组件:
抽象原型类:规定了具体原型对象必须实现的接口。
具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
访问类:使用具体原型类中的 clone() 方法来复制新的对象。

类图.png

package com.lillcol.designmodel;

/**
 * @author lillcol
 * 2019/6/17-21:48
 */
public class Prototype {
    public static void main(String[] args) throws CloneNotSupportedException {
        Realizetype realizetype = new Realizetype();
        Realizetype clone = (Realizetype)realizetype.clonePrototype();
        System.out.println("realizetype==clone?  "+ (realizetype==clone));
    }
}


abstract class AbstractPrototype implements Cloneable{
    abstract Object clonePrototype() throws CloneNotSupportedException;
}
class Realizetype  extends   AbstractPrototype{
    Realizetype(){
        System.out.println("Real  King of Monkey");
    }
    Object clonePrototype() throws CloneNotSupportedException {
        System.out.println("fake King of Monkey");
        return (Realizetype)super.clone();
    }
}

//输出结果:
Real  King of Monkey
fake King of Monkey
realizetype==clone?  false

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。
在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。

  • Builder 构建器

模式定义:
将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)。

建造者(Builder)模式组件:
产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个滅部件。
抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
具体建造者(ConcreteBuilder):实现 Builder接口,完成复杂产品的各个部件的具体创建方法。
指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

类图.png

package com.lillcol.designmodel;

/**
 * @author lillcol
 * 2019/6/17-22:32
 */
//组装电脑
public abstract class Builder {
    Product product = new Product();

    abstract void buyKey();

    abstract void buyMouse();

    abstract Product returnComputer();
}


class ConcreteBuilder1 extends Builder {

    @Override
    void buyKey() {
        product.setKey("ConcreteBuilder1 key :双飞燕无线鼠标");
    }

    @Override
    void buyMouse() {
        product.setMouse("ConcreteBuilder1 mouse :双飞燕机械键盘");
    }

    @Override
    Product returnComputer() {
        return product;
    }
}

class ConcreteBuilder2 extends Builder {

    @Override
    void buyKey() {
        product.setKey("ConcreteBuilder1 key :无线鼠标");
    }

    @Override
    void buyMouse() {
        product.setMouse("ConcreteBuilder1 mouse :雷柏机械键盘");
    }

    @Override
    Product returnComputer() {
        return product;
    }
}

class Product {
    String key;

    String mouse;

    public void setKey(String key) {
        this.key = key;
    }

    public void setMouse(String mouse) {
        this.mouse = mouse;
    }

    public void show() {
        System.out.println(key + "    " + mouse);
    }
}

class Director {
    Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public Product construct() {
        builder.buyKey();
        builder.buyMouse();
        return builder.returnComputer();
    }

}

class BuilderTest {
    public static void main(String[] args) {
        ConcreteBuilder1 concreteBuilder1 = new ConcreteBuilder1();
        Director dirctor = new Director(concreteBuilder1);
        Product product = dirctor.construct();
        product.show();
        System.out.println("-----------------");
        ConcreteBuilder2 concreteBuilder2 = new ConcreteBuilder2();
        Director dirctor2 = new Director(concreteBuilder2);
        Product product2 = dirctor2.construct();
        product2.show();

    }
}

//输出结果:
ConcreteBuilder1 key :双飞燕无线鼠标    ConcreteBuilder1 mouse :双飞燕机械键盘
-----------------
ConcreteBuilder1 key :无线鼠标    ConcreteBuilder1 mouse :雷柏机械键盘

优点:

  1. 各个具体的建造者相互独立,有利于系统的扩展。
  2. 客户端不必知道产品内部组成的细节,便于控制细节风险。

缺点:

  1. 产品的组成部分必须相同,这限制了其使用范围。
  2. 如果产品的内部变化复杂,该模式会增加很多的建造者类。

参考文档:
http://c.biancheng.net/view/1364.html
李建忠23中设计模式

posted @ 2019-07-04 00:19  lillcol  阅读(529)  评论(0编辑  收藏  举报