推荐答案
工厂模式 (Factory Pattern) 的概念和作用
工厂模式是一种创建型设计模式,它提供了一种创建对象的方式,而无需指定具体的类。工厂模式的核心思想是将对象的创建过程封装在一个工厂类中,客户端只需通过工厂类来获取所需的对象,而不需要关心对象的具体实现细节。
工厂模式的主要作用包括:
- 解耦:将对象的创建与使用分离,降低代码的耦合度。
- 扩展性:当需要添加新的产品时,只需扩展工厂类,而不需要修改现有的代码。
- 复用性:工厂类可以复用,减少重复代码。
简单工厂、工厂方法和抽象工厂的区别
简单工厂模式 (Simple Factory):
- 简单工厂模式通过一个工厂类来创建所有产品,客户端只需传入产品类型,工厂类根据类型返回相应的产品。
- 优点:实现简单,适合产品种类较少的情况。
- 缺点:当产品种类增多时,工厂类会变得臃肿,不符合开闭原则。
工厂方法模式 (Factory Method):
- 工厂方法模式定义了一个创建对象的接口,但由子类决定实例化哪个类。每个产品都有对应的工厂子类。
- 优点:符合开闭原则,扩展性好。
- 缺点:每增加一个产品,就需要增加一个工厂类,类的数量会增多。
抽象工厂模式 (Abstract Factory):
- 抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式通常包含多个工厂方法。
- 优点:可以创建一系列相关的产品,适合产品族的情况。
- 缺点:扩展新的产品族较为复杂,需要修改抽象工厂接口及其所有子类。
本题详细解读
工厂模式的应用场景
工厂模式适用于以下场景:
- 当一个类无法预知它需要创建的对象类型时。
- 当一个类希望由其子类来指定创建的对象时。
- 当需要将对象的创建过程集中管理,以便于维护和扩展时。
简单工厂模式的实现
// www.javascriptcn.com code example
class ProductA {
use() {
console.log('Using Product A');
}
}
class ProductB {
use() {
console.log('Using Product B');
}
}
class SimpleFactory {
createProduct(type) {
switch (type) {
case 'A':
return new ProductA();
case 'B':
return new ProductB();
default:
throw new Error('Unknown product type');
}
}
}
const factory = new SimpleFactory();
const productA = factory.createProduct('A');
productA.use(); // Output: Using Product A工厂方法模式的实现
// www.javascriptcn.com code example
class ProductA {
use() {
console.log('Using Product A');
}
}
class ProductB {
use() {
console.log('Using Product B');
}
}
class Factory {
createProduct() {
throw new Error('This method must be overridden');
}
}
class ProductAFactory extends Factory {
createProduct() {
return new ProductA();
}
}
class ProductBFactory extends Factory {
createProduct() {
return new ProductB();
}
}
const factoryA = new ProductAFactory();
const productA = factoryA.createProduct();
productA.use(); // Output: Using Product A抽象工厂模式的实现
// www.javascriptcn.com code example
class ProductA1 {
use() {
console.log('Using Product A1');
}
}
class ProductA2 {
use() {
console.log('Using Product A2');
}
}
class ProductB1 {
use() {
console.log('Using Product B1');
}
}
class ProductB2 {
use() {
console.log('Using Product B2');
}
}
class AbstractFactory {
createProductA() {
throw new Error('This method must be overridden');
}
createProductB() {
throw new Error('This method must be overridden');
}
}
class ConcreteFactory1 extends AbstractFactory {
createProductA() {
return new ProductA1();
}
createProductB() {
return new ProductB1();
}
}
class ConcreteFactory2 extends AbstractFactory {
createProductA() {
return new ProductA2();
}
createProductB() {
return new ProductB2();
}
}
const factory1 = new ConcreteFactory1();
const productA1 = factory1.createProductA();
productA1.use(); // Output: Using Product A1
const factory2 = new ConcreteFactory2();
const productA2 = factory2.createProductA();
productA2.use(); // Output: Using Product A2