工厂模式模式的定义与特点
- 工厂模式(Factory Pattern)是编程中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
- 简单工厂模式:专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。它又称为静态工厂方法模式。它的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
- 工厂方法模式:模式的表现只是一个抽象的方法。提前定义用于创建对象的接口,让子类(具体工厂)决定实例化具体的某一个类,即在工厂和产品中间增加接口(抽象工厂),工厂不再负责产品的创建,由接口针对不同条件返回具体的类实例,由具体类实例(具体工厂)去实现。
- 抽象工厂模式:是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
工厂模式的优点和缺点
- 简单工厂模式:可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅"消费"产品。外界与具体类隔离开来,偶合性低。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
- 工厂方法模式:。简单工厂模式的工厂类随着产品类的增加需要增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。工厂方法模式完全满足OCP,即它有非常良好的扩展性。
- 抽象工厂模式有助于这样的团队的分工,降低了模块间的耦合性,提高了团队开发效率。
- 简单工厂模式:当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类集中了所有产品创建逻辑,一旦增加产品或者删除产品,整个系统都要受到影响。系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,违背了"开放--封闭"原则(OCP).另外,简单工厂模式通常使用静态工厂方法,这使得无法由子类继承,造成工厂角色无法形成基于继承的等级结构。
- 工厂方法模式:假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦。比如说,每增加一个产品,相应的也要增加一个子工厂,会加大了额外的开发量。
- 抽象工厂模式:抽象工厂模式在于难于应付“新对象”的需求变动。难以支持新种类的产品。难以扩展抽象工厂以生产新种类的产品。这是因为抽象工厂几乎确定了可以被创建的产品集合,支持新种类的产品就需要扩展该工厂接口,这将涉及抽象工厂类及其所有子类的改变。
抽象工厂模式例子
// 超级工厂类
class Factory {
constructor(choice) {
choice = choice.toLocaleLowerCase();
switch (choice) {
case "person":
return new Person();
case "animal":
return new Animal();
default:
break;
}
}
}
// 准备工厂类
class AbstractFactory {
// getPerson属于Person类的方法
getPerson() {
throw new Error("子类请实现接口");
}
// getAnimal属于Animaln类的方法
getAnimal() {
throw new Error("子类请实现接口");
}
}
// Dog和Cat是属于Animate的产品
class Dog {
run() {
console.log("狗");
}
}
class Cat {
run() {
console.log("猫");
}
}
// Male 和 Female 属于 Person 工厂的产品
class Male {
run() {
console.log("男性");
}
}
class Female {
run() {
console.log("女性");
}
}
class Person extends AbstractFactory {
getPerson(person) {
person = person.toLocaleLowerCase();
switch (person) {
case "male":
return new Male();
case "female":
return new Female();
default:
break;
}
}
getAnimal() {
return null;
}
}
class Animal extends AbstractFactory {
getPerson() {
return null;
}
getAnimal(animal) {
animal = animal.toLocaleLowerCase();
switch (animal) {
case "cat":
return new Cat();
case "dog":
return new Dog();
default:
break;
}
}
}
// 实现Person类
const person = new Factory("person");
const male = person.getPerson("male"),
female = person.getPerson("female");
male.run();
female.run();
// 实现 Animate 类
const animal = new Factory("animal");
const dog = animal.getAnimal("dog"),
cat = animal.getAnimal("cat");
dog.run();
cat.run();