【技术积累】软件设计模式中的工厂模式【一】
什么是工厂模式?
工厂模式是一种设计模式,它利用工厂类来创建对象,而不是在程序中直接实例化对象。
工厂模式可以隐藏创建对象的具体细节,提高代码可维护性和可扩展性。
其核心思想是将对象的创建与具体实现分离开来,通过工厂类统一管理对象的创建,使得客户端无需了解创建对象的具体实现。
工厂类根据客户端请求的不同,返回不同的对象实例。
工厂模式主要包括三种方式:简单工厂模式、工厂方法模式和抽象工厂模式。
什么是简单工厂模式?
简单工厂模式(Simple Factory Pattern),又称静态工厂模式,是一种常见的设计模式之一,它是由一个工厂对象决定创建出哪一种产品类的实例,而客户端不需要知道具体实现类的类名,只需要知道所需产品的类型即可。
简单工厂模式的核心思想是将多个具有共同特征的产品类抽象成一个产品类,并创建一个工厂类来生成这些产品的实例。
这样,客户端只需要传递一个参数给工厂类即可实现创建实例的功能,使得客户端与具体实现类解耦,使得后期维护更加方便。
好比去餐厅吃饭,你只需要跟服务员点菜(请求产品),告诉服务员你想要吃什么菜(指定对象类型),服务员就会为你送上菜(返回对象)。
你不需要知道菜是如何做出来的(对象是如何创建的),只需要享受美食。
这就是简单工厂模式对于对象的创建过程进行了封装,让使用者不需要知道具体的实现过程,更加方便快捷。
// 定义产品抽象类
abstract class Product {
public abstract void use();
}
// 定义具体产品类
class ProductA extends Product {
public void use() {
System.out.println("使用产品A");
}
}
class ProductB extends Product {
public void use() {
System.out.println("使用产品B");
}
}
// 定义工厂类
class Factory {
public static Product createProduct(String type) {
if (type.equals("A")) {
return new ProductA();
} else if (type.equals("B")) {
return new ProductB();
} else {
return null;
}
}
}
// 客户端使用工厂来创建产品实例
public static void main(String[] args) {
Product product = Factory.createProduct("A");
product.use();
}
简单工厂模式的优点和缺点
简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它提供了一种简单、通用的方式来创建对象,实现了对客户端代码的解耦使得客户端不需要知道对象的具体实现。下面分别详细介绍简单工厂模式的优点和缺点,以及分别用Java伪代码演示。
优点:
1. 降低客户端的耦合度:客户端只需要知道工厂类即可,不需要知道具体的产品类,使得客户端代码与具体类的实现解耦。
2. 客户端不需要知道对象的创建过程:只需要知道工厂类提供的接口即可,无需了解具体对象的创建过程,使得客户端更加容易使用产品类。
3. 工厂方法有利于横向扩展:可以很容易扩展出新的产品类,只需要编写新的产品子类和工厂方法即可。
缺点:
1. 工厂类的职责相对较重,不易于扩展:如果需要添加新的产品类,需要修改工厂类的代码,可能会引起潜在的风险。
2. 不符合开闭原则:增加新的产品需要修改工厂类的代码,不符合开闭原则。
3. 简单工厂类只能创建单一类型的产品,无法满足多种产品的需求。
Java伪代码演示简单工厂模式
//先定义一个抽象产品接口:
public interface Product {
void run();
}
//再定义具体产品类:
public class ProductA implements Product {
@Override
public void run() {
System.out.println("ProductA is running.");
}
}
public class ProductB implements Product {
@Override
public void run() {
System.out.println("ProductB is running.");
}
}
//定义一个简单的工厂类:
public class SimpleFactory {
public static Product createProduct(int type) {
if (type == 1) {
return new ProductA();
} else if (type == 2) {
return new ProductB();
} else {
return null;
}
}
}
优点的演示:
public class Client {
public static void main(String[] args) {
Product product = SimpleFactory.createProduct(1);
if (product != null) {
product.run();
} else {
System.out.println("Invalid type.");
}
}
}
这样就可以实现客户端代码与具体类的实现解耦,客户端只需要知道工厂类即可。
缺点的演示:
public class Client {
public static void main(String[] args) {
Product product = SimpleFactory.createProduct(3);
if (product != null) {
product.run();
} else {
System.out.println("Invalid type.");
}
}
}
当传入参数为3时,会返回null,表示无效的类型,这样就需要修改工厂类的代码,不符合开闭原则。
简单工厂模式的组成部分和工作流程是什么?如何创建一个简单工厂模式
简单工厂模式的组成部分包括:
- 工厂类:负责创建产品的类,通常是一个静态工厂方法,根据不同的参数生成不同的产品。
- 抽象产品类:定义产品的抽象方法或接口,是具体产品类的父类。
- 具体产品类:实现抽象产品类定义的方法或接口,是由工厂类创建的产品。
简单工厂模式的工作流程是:
- 客户端通过调用工厂类的静态工厂方法并传递相应的参数,请求创建产品。
- 工厂类根据传递的参数创建对应的具体产品类实例。
- 工厂类将创建的产品返回给客户端。
- 客户端使用产品实例执行相应的操作。
下面是简单工厂模式的实现步骤:
- 创建一个抽象产品接口:定义了所有产品必须实现的方法。
- 创建具体产品类:实现抽象产品接口,并定义特定于该产品的方法。
- 创建一个工厂类:工厂类包含一个用于创建产品的方法。该方法接受一个参数(通常是一个枚举值或一个字符串),根据参数值的不同返回不同的具体产品对象。
- 在客户端代码中使用工厂类:通过调用工厂类的静态方法,根据需要获取产品。
代码可参照上一个问题的案例
简单工厂模式适用于哪些场景
简单工厂模式适用于以下场景:
- 需要创建的对象较少,通常不超过5个。
- 对象的生成过程比较简单,只需要根据输入参数选择不同的构造方式即可。
- 客户端不需要知道对象的具体类名,只需要知道对象的类型即可。
- 不需要通过继承来实现不同产品之间的差异,只需要通过同一个工厂来创建不同类型的产品即可。
- 最初设计时不确定对象会有哪些具体的子类,但仍然需要通过某种方式来创建这些对象。这时可以先在工厂中添加这些对象,后续再根据需求修改工厂的实现。
总之,简单工厂模式适合于对象较少、生成过程简单、无需知道具体类名、不需要通过继承来实现差异、允许动态修改工厂实现等情况。但是,随着业务增长,可能会变得难以维护,因为所有的创建逻辑都在一个工厂中,容易导致代码量增加、逻辑复杂等问题。因此,在选择使用简单工厂模式时应该注意这些风险,并考虑是否需要更复杂的创建模式来满足业务需求。
简单工厂模式客户端如何处理产品对象的创建异常
简单工厂模式是一种创建型设计模式,其目的是在不暴露创建逻辑的情况下创建对象。但是,当创建过程中出现异常时,客户端需要处理异常,以避免应用程序崩溃。
在简单工厂模式中,客户端通过工厂类创建产品对象。如果创建过程中出现异常,则工厂类需要抛出异常。客户端可以捕获异常,并相应地处理它。
假设有一个形状工厂类,它可以创建不同类型的形状,例如圆形、矩形和三角形。客户端通过提供形状类型来请求创建相应的形状对象。
public class ShapeFactory {
public Shape createShape(String shapeType) throws InvalidShapeException {
switch (shapeType) {
case "circle":
return new Circle();
case "rectangle":
return new Rectangle();
case "triangle":
return new Triangle();
default:
throw new InvalidShapeException("Invalid shape type provided: " + shapeType);
}
}
}
在这个工厂类中,如果客户端提供一个无效的形状类型,则会抛出一个无效形状异常(InvalidShapeException)。客户端可以通过捕获此类异常来处理创建过程中的异常。以下是客户端如何处理异常的示例伪代码
try {
ShapeFactory shapeFactory = new ShapeFactory();
Shape circle = shapeFactory.createShape("circle");
Shape rectangle = shapeFactory.createShape("rectangle");
Shape triangle = shapeFactory.createShape("triangle");
Shape square = shapeFactory.createShape("square"); //Invalid Shape Type
} catch (InvalidShapeException e) {
System.out.println(e.getMessage());
}
在上述示例中,当客户端请求创建一个无效形状时,工厂类将抛出一个InvalidShapeException。客户端通过捕获此异常并打印其消息来处理创建过程中的异常。
通过这种方式,客户端可以在简单工厂模式中处理异常,并且可以使应用程序从异常中恢复。
抽象工厂模式是什么
抽象工厂模式是一种创建型设计模式,它提供接口用于创建一系列相关或依赖对象,而不需要指定它们的具体类。抽象工厂模式允许客户端使用抽象接口和实现接口分离的方式来创建一组相关的对象。
抽象工厂模式中包含抽象工厂、具体工厂、抽象产品和具体产品四个角色。
- 抽象工厂定义了一组用于创建抽象产品的接口
- 具体工厂实现了抽象工厂中定义的接口,用于生产一组具体产品
- 抽象产品定义了一组用于操作产品的接口
- 具体产品实现了抽象产品中定义的接口。
使用抽象工厂模式,如果需要增加一种产品系列,则只需添加一个新的具体工厂和一组具体产品,而不需要改变已有的代码。
这种模式可以有效地减少代码的耦合性,提高系统的扩展性和灵活性。
抽象工厂模式就是一个厂家能够生产多个系列产品,例如一个化妆品公司可以生产多个系列的护肤品和化妆品。
为了让生产过程更加标准和规范化,该公司会设计多个生产线,每条生产线专门生产一种系列产品。每条生产线里都有专门的设备和加工工艺,不能互相混用,例如生产基础护肤品的生产线不能生产高端抗衰老护肤品。
这时,抽象工厂模式就很适用了。该公司设计一个抽象工厂接口,用于生产一类产品,然后各个生产线分别实现该接口,并且生产出来的产品都要符合该接口标准。这样,不同生产线之间可以互相替换,客户端也无需知道具体的生产过程,只需通过访问抽象工厂接口来获取需要的产品就可以了。
//首先,定义产品族的抽象基类 AbstractProductA 和 AbstractProductB:
public abstract class AbstractProductA {
public abstract void use();
}
public abstract class AbstractProductB {
public abstract void eat();
}
//然后,定义不同产品的具体实现类 ProductA1、ProductA2、ProductB1 和 ProductB2:
public class ProductA1 extends AbstractProductA {
public void use() {
System.out.println("Product A1 is used");
}
}
public class ProductA2 extends AbstractProductA {
public void use() {
System.out.println("Product A2 is used");
}
}
public class ProductB1 extends AbstractProductB {
public void eat() {
System.out.println("Product B1 is eaten");
}
}
public class ProductB2 extends AbstractProductB {
public void eat() {
System.out.println("Product B2 is eaten");
}
}
//接着,定义抽象工厂接口 AbstractFactory,包含用于创建产品族的接口方法:
public interface AbstractFactory {
public AbstractProductA createProductA();
public AbstractProductB createProductB();
}
//然后,定义具体的工厂类 ConcreteFactory1 和 ConcreteFactory2,分别实现 AbstractFactory 接口并实现其中的方法:
public class ConcreteFactory1 implements AbstractFactory {
public AbstractProductA createProductA() {
return new ProductA1();
}
public AbstractProductB createProductB() {
return new ProductB1();
}
}
public class ConcreteFactory2 implements AbstractFactory {
public AbstractProductA createProductA() {
return new ProductA2();
}
public AbstractProductB createProductB() {
return new ProductB2();
}
}
//最后,客户端只需要访问抽象工厂接口,具体工厂的实例化和具体产品的创建都被封装到工厂内部:
public class Client {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
AbstractProductA productA1 = factory1.createProductA();
AbstractProductB productB1 = factory1.createProductB();
productA1.use();
productB1.eat();
AbstractFactory factory2 = new ConcreteFactory2();
AbstractProductA productA2 = factory2.createProductA();
AbstractProductB productB2 = factory2.createProductB();
productA2.use();
productB2.eat();
}
}
//输出结果为:
Product A1 is used
Product B1 is eaten
Product A2 is used
Product B2 is eaten
//这样,就通过抽象工厂模式创建了不同的产品族,并且客户端与具体产品类实现解耦了。
抽象工厂模式与简单工厂模式的区别
抽象工厂模式和简单工厂模式都是面向对象的创建型设计模式,它们的主要区别在于以下几个方面:
1.抽象工厂模式可以创建一系列关联的产品,而简单工厂只能创建一个产品。
2.在抽象工厂模式中,有多个抽象产品类,每个抽象产品类可以有多个具体产品类实现,而简单工厂模式中,只有一个抽象产品类和一个具体产品类。
3.抽象工厂模式通常是面向一个产品等级结构的,可以扩展不同的产品系列,而简单工厂模式是面向单一产品的。
4.抽象工厂模式要求客户端代码使用抽象接口来创建一组相关的产品对象,而简单工厂模式仅需要一个传递一些参数和一个实例化对象。
5.抽象工厂模式的适用范围比简单工厂模式更广,但实现抽象工厂模式的成本也更高。简单工厂模式较为简单易懂,易于使用和实现。
总之,抽象工厂模式适用于需求变动较频繁,需要同时创建多个产品族的场景。而简单工厂模式适用于创建单一产品,且该产品创建的逻辑不随需求变动。
综上所述,抽象工厂模式和简单工厂都有自己的特点和应用场景,需要根据具体需求选择合适的工厂模式来实现代码。