• 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中设计模式

  • 相关阅读:
    【和我一起学习Unity3D】Unity3D的坐标控制
    android开发利器--站在巨人肩膀上前行
    Ubuntu输入password登陆后又跳回到登录界面
    Leetcode:Swap Nodes in Pairs 单链表相邻两节点逆置
    Android Home键监听
    Android 6.0 中TimePicker显示为滚动样式的方法
    Android Calendar的运用
    Android中Calendar类的用法总结
    Androlid入门之文件系统操作(三)文件读写
    Android入门之文件系统操作(二)文件操作相关指令
  • 原文地址:https://www.cnblogs.com/lillcol/p/11129940.html
Copyright © 2020-2023  润新知