创建型设计模式(下)

简单工厂模式:

  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 cats: Cat = new Cat();
        return cats;
    }
}

let theCat: CatFactor = new CatFactor();
theCat.createAnimal().speak();
theCat.createAnimal().leg();

抽象工厂模式:

  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

猜你喜欢

转载自www.cnblogs.com/lemonyam/p/11617480.html
今日推荐