定义
简单工厂模式是一种创建型设计模式,它提供了一个统一的接口来创建不同类型的对象,而无需暴露对象的具体创建逻辑。简单工厂模式由三个主要组件组成:
-
工厂(Factory):负责创建对象的工厂类。它包含一个静态方法或实例方法,根据传入的参数或条件判断来实例化并返回具体的产品对象。
-
产品(Product):抽象产品类或接口,定义了产品的共同属性和方法。
-
具体产品(Concrete Product):实现了产品接口或继承了抽象产品类,提供了具体的产品实现。
简单工厂模式通过将对象的创建逻辑封装在工厂类中,使得客户端代码与具体产品的创建过程解耦。客户端只需要通过工厂类来请求所需的产品,而无需关心产品的具体创建细节。这样可以实现代码的灵活性和可维护性,方便后续对产品的扩展和修改。
简单工厂模式适用于以下场景:
- 需要创建的对象较少,且对象的创建逻辑相对简单。
- 客户端代码不需要关心具体产品的创建细节,只需通过工厂类来创建所需产品。
- 需要对产品的创建过程进行集中管理和控制。
需要注意的是,简单工厂模式的一个限制是在添加新产品时,需要修改工厂类的代码,违反了开闭原则。如果需要频繁添加新产品,可以考虑使用工厂方法模式或抽象工厂模式来解决该问题。
示例一:
假设我们有一个图形类 Shape,它有两个子类 Circle(圆形)和 Rectangle(矩形),我们通过简单工厂模式创建这些图形对象:
// 抽象图形类
abstract class Shape {
abstract void draw();
}
// 具体图形类 - 圆形
class Circle extends Shape {
@Override
void draw() {
System.out.println("绘制圆形");
}
}
// 具体图形类 - 矩形
class Rectangle extends Shape {
@Override
void draw() {
System.out.println("绘制矩形");
}
}
// 简单工厂类
class ShapeFactory {
// 根据传入的参数创建对应的图形对象
public static Shape createShape(String shapeType) {
if (shapeType.equalsIgnoreCase("circle")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("rectangle")) {
return new Rectangle();
} else {
throw new IllegalArgumentException("Unsupported shape type: " + shapeType);
}
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Shape circle = ShapeFactory.createShape("circle");
circle.draw();
Shape rectangle = ShapeFactory.createShape("rectangle");
rectangle.draw();
}
}
在上述示例中,我们定义了抽象图形类 Shape,并有两个具体图形类 Circle(圆形)和 Rectangle(矩形),它们都继承自 Shape 类。然后我们创建了一个简单工厂类 ShapeFactory,其中的 createShape 方法根据传入的参数来创建对应的图形对象。
在客户端代码中,我们通过调用 ShapeFactory.createShape 方法来获取具体的图形对象,并调用其 draw 方法来绘制图形。这样,客户端代码无需知道具体的图形对象是如何创建的,只需通过简单工厂来获取所需的图形对象,实现了客户端与具体对象创建过程的解耦。
输出结果:
绘制圆形
绘制矩形
示例二
假设我们有一个饮料店,它提供多种饮料,包括咖啡、茶和果汁。我们可以使用简单工厂模式来创建这些饮料对象:
// 抽象饮料类
abstract class Beverage {
abstract void prepare();
abstract void serve();
}
// 具体饮料类 - 咖啡
class Coffee extends Beverage {
@Override
void prepare() {
System.out.println("准备咖啡");
}
@Override
void serve() {
System.out.println("上咖啡");
}
}
// 具体饮料类 - 茶
class Tea extends Beverage {
@Override
void prepare() {
System.out.println("准备茶");
}
@Override
void serve() {
System.out.println("上茶");
}
}
// 具体饮料类 - 果汁
class Juice extends Beverage {
@Override
void prepare() {
System.out.println("准备果汁");
}
@Override
void serve() {
System.out.println("上果汁");
}
}
// 简单工厂类
class BeverageFactory {
// 根据传入的参数创建对应的饮料对象
public static Beverage createBeverage(String beverageType) {
if (beverageType.equalsIgnoreCase("coffee")) {
return new Coffee();
} else if (beverageType.equalsIgnoreCase("tea")) {
return new Tea();
} else if (beverageType.equalsIgnoreCase("juice")) {
return new Juice();
} else {
throw new IllegalArgumentException("Unsupported beverage type: " + beverageType);
}
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Beverage coffee = BeverageFactory.createBeverage("coffee");
coffee.prepare();
coffee.serve();
Beverage tea = BeverageFactory.createBeverage("tea");
tea.prepare();
tea.serve();
Beverage juice = BeverageFactory.createBeverage("juice");
juice.prepare();
juice.serve();
}
}
在上述示例中,我们定义了抽象饮料类 Beverage,并有三个具体饮料类 Coffee(咖啡)、Tea(茶)和 Juice(果汁),它们都继承自 Beverage 类。然后我们创建了一个简单工厂类 BeverageFactory,其中的 createBeverage 方法根据传入的参数来创建对应的饮料对象。
在客户端代码中,我们通过调用 BeverageFactory.createBeverage 方法来获取具体的饮料对象,并调用其 prepare 和 serve 方法来准备和上菜饮料。这样,客户端代码无需知道具体的饮料对象是如何创建的,只需通过简单工厂来获取所需的饮料对象,实现了客户端与具体对象创建过程的解耦。
输出结果:
准备咖啡
上咖啡
准备