zoukankan      html  css  js  c++  java
  • 创建型设计模式(下)

    简单工厂模式:

      1、定义:根据参数的不同返回不同类的实例

      2、模式结构:

        (1)工厂角色(Factory):实现创建所有实例的内部逻辑

        (2)抽象产品角色(Product):所创建的所有对象的父类,负责描述所有实例所共有的公共接口

        (3)具体产品角色(ConcreteProduct):创建目标,所有创建的对象都充当这个角色的某个具体类的实例

      3、优点:

        (1)工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,通过这种做法实现了对责任的分割

        (2)客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可

        (3)通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类

          在一定程度上提高了系统的灵活性

      4、缺点:

        (1)工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响

        (2)在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护

        (3)系统扩展困难,一旦添加新产品就不得不修改工厂逻辑

      5、适用场景:

        (1)工厂类负责创建的对象比较少

        (2)客户端只知道传入工厂类的参数,对于如何创建对象不关心

    // Abstract Product
    interface Car {
        carGreet(): void;
    }
    // ConcreteProduct
    class Moto implements Car {
        carGreet(): void {
            console.log("Moto says hello...");
        }
    }
    class Bike implements Car {
        carGreet(): void {
            console.log("Bike says hello...");
        }
    }
    // Factory
    class Factory {
        createCar(carName: string): Car {
            if (carName === "Moto")
                return new Moto();
            else if (carName === "Bike")
                return new Bike();
            return null;
        }
    }
    
    let carFactory: Factory = new Factory();
    carFactory.createCar("Moto").carGreet();    // Moto says hello...
    carFactory.createCar("Bike").carGreet();    // Bike says hello...

    工厂方法模式:

      1、定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中

      2、模式结构:

        (1)抽象产品(Product):所创建产品的父类,给出一个抽象接口或抽象类,一般由具体产品类具体实现

        (2)具体产品(ConcreteProduct):抽象产品类的实现类,为实现某个具体产品的对象

        (3)抽象工厂(Factory):工厂方法模式的核心(简单工厂模式无此抽象类),与应用程序无关。

                      是具体工厂必须实现的接口或者必须继承的父类

        (4)具体工厂(ConcreteFactory):继承抽象工厂类,实现具体业务逻辑

      3、优点:

        (1)用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名

        (2)工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部

        (3)使用工厂方法模式的另一个优点是在系统中加入新产品时,

          只要添加一个具体工厂和具体产品就可以了,完全符合“开闭原则”

    注:开闭原则,对于扩展是开放的,对于修改是关闭

      4、缺点:

        (1)在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类

        (2)由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,

           增加了系统的抽象性和理解难度

      5、适用场景:

        (1)一个类不知道它所需要的对象的类

        (2)一个类通过其子类来指定创建哪个对象

        (3)将创建对象的任务委托给多个工厂子类中的某一个,需要时动态指定

    // 抽象产品
    abstract class Animal {
        abstract speak(): void;
        abstract leg(): void;
    }
    // 具体产品
    class Cat extends Animal {
        speak(): void {
            console.log("miao miao miao");
        }
        leg(): void {
            console.log("cat has four legs");
        }
    }
    class Dog extends Animal {
        speak(): void {
            console.log("wang wang wang");
        }
        leg(): void {
            console.log("dog has four legs")
        }
    }
    // 抽象工厂
    abstract class AnimalFactor {
        abstract createAnimal(): Animal;
    }
    // 具体工厂
    class CatFactor extends AnimalFactor {
        createAnimal(): Animal{
            let cat: Cat = new Cat();
            return cat;
        }
    }
    class DogFactory extends AnimalFactor {
        createAnimal(): Animal {
            let dog: Dog = new Dog();
            return dog;
        }
    }
    
    let animal: AnimalFactor = new CatFactor();
    animal.createAnimal().speak();
    animal.createAnimal().leg();
    animal = new DogFactory();
    animal.createAnimal().speak();

    抽象工厂模式:

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

      2、模式结构:

        (1)抽象工厂(AbstractFactory):声明生成抽象产品的方法

        (2)具体工厂(ConcreteFactory):实现了抽象工厂声明的生成抽象产品的方法,生成一组具体产品,

                            这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中

        (3)抽象产品(AbstractProduct):为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法

        (4)具体产品(Product):定义具体工厂生产的具体产品对象,实现抽象产品接口中定义的业务方法

    注:

      (1)产品等级结构:即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,

                  抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,
                 抽象电视机是父类,而具体品牌的电视机是其子类
      (2)产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品
            如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,
             海尔电冰箱位于电冰箱产品等级结构中

      3、优点:

        (1)抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建

        (2)当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象

        (3)增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”

      4、缺点:

        (1)在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品

        (2)“开闭原则”的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)

      5、适用场景:

        (1)系统中有多于一个的产品族,而每次只使用其中某一产品族

        (2)属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来

        (3)系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现

    注:一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的

    // 抽象产品
    abstract class Mouse {
        abstract sayHi(): void;
    }
    
    abstract class Keybo {
        abstract sayHi(): void;
    }
    
    // 抽象工厂
    abstract class PCFactory {
        abstract createMouse(): Mouse;
        abstract createKeybo(): Keybo;
    }
    
    // 具体产品
    class DellMouse extends Mouse {
        sayHi() {
            console.log("DellMouse say hi");
        }
    }
    class HpMouse extends Mouse {
        sayHi() {
            console.log("HpMouse say hi");
        }
    }
    class DellKeybo extends Keybo {
        sayHi() {
            console.log("DellKeybo say hi");
        }
    }
    class HpKeybo extends Keybo {
        sayHi() {
            console.log("HpKeybo say hi");
        }
    }
    
    // 具体工厂
    class DellFactory extends PCFactory {
        createMouse() {
            return new DellMouse();
        }
        createKeybo() {
            return new DellKeybo();
        }
    }
    class HPFactory extends PCFactory {
        createMouse() {
            return new HpMouse();
        }
        createKeybo() {
            return new HpKeybo();
        }
    }
    
    let dell: DellFactory = new DellFactory();
    let hp: HPFactory = new HPFactory();
    dell.createMouse().sayHi(); // DellMouse say hi
    dell.createKeybo().sayHi(); // DellKeybo say hi
    hp.createMouse().sayHi();   // HpMouse say hi
    hp.createKeybo().sayHi();   // HpKeybo say hi
  • 相关阅读:
    计算机体系结构的铁律(iron law)
    PHP 画图——使用jpgraph画图
    理解Paxos Made Practical
    【bzoj1015】【JSOI2008】【星球大战】【并查集+离线】
    Spark调研笔记第3篇
    hduoj2094产生冠军
    使用HD/IDE层的ioctl接口获取磁盘容量get_hdd_max_sector
    给GridView设置行高
    tomcat的一些简单配置
    【JavaScript】--JavaScript总结一览无余
  • 原文地址:https://www.cnblogs.com/lemonyam/p/11617480.html
Copyright © 2011-2022 走看看