Design Patterns教程-工厂方法模式
工厂模式或工厂方法模式的意思是定义一个用于创建对象的接口或抽象类,但由子类决定实例化哪一个类。换句话说,子类负责创建类的实例。
工厂方法模式也被称为虚拟构造函数。
工厂设计模式的优点
- 工厂方法模式允许子类选择创建对象的类型。
- 它通过消除将应用程序特定类绑定到代码中的需要来促进松耦合。这意味着代码只与结果接口或抽象类交互,因此它将与实现该接口或扩展该抽象类的任何类一起工作。
工厂设计模式的使用场景
- 当一个类不知道需要创建哪些子类时。
- 当一个类希望其子类指定要创建的对象时。
- 当父类将创建对象的职责委托给子类时。
工厂方法模式的 UML
- 我们将创建一个 Plan 抽象类和扩展 Plan 抽象类的具体类。下一步定义一个工厂类 GetPlanFactory。
- GenerateBill 类将使用 GetPlanFactory 获取 Plan 对象。它将向 GetPlanFactory 传递信息(DOMESTICPLAN / COMMERCIALPLAN / INSTITUTIONALPLAN)以获取所需类型的对象。
计算电费:工厂方法的实际示例
步骤 1: 创建一个 Plan 抽象类。
import java.io.*;
abstract class Plan {
protected double rate;
abstract void getRate();
public void calculateBill(int units) {
System.out.println(units * rate);
}
} // Plan 类结束
步骤 2: 创建扩展 Plan 抽象类的具体类。
class DomesticPlan extends Plan {
@Override
public void getRate() {
rate = 3.50;
}
} // DomesticPlan 类结束
class CommercialPlan extends Plan {
@Override
public void getRate() {
rate = 7.50;
}
} // CommercialPlan 类结束
class InstitutionalPlan extends Plan {
@Override
public void getRate() {
rate = 5.50;
}
} // InstitutionalPlan 类结束
步骤 3: 创建一个 GetPlanFactory 来根据给定信息生成具体类的对象。
class GetPlanFactory {
// 使用 getPlan 方法获取 Plan 类型的对象
public Plan getPlan(String planType) {
if (planType == null) {
return null;
}
if (planType.equalsIgnoreCase("DOMESTICPLAN")) {
return new DomesticPlan();
} else if (planType.equalsIgnoreCase("COMMERCIALPLAN")) {
return new CommercialPlan();
} else if (planType.equalsIgnoreCase("INSTITUTIONALPLAN")) {
return new InstitutionalPlan();
}
return null;
}
} // GetPlanFactory 类结束
步骤 4: 通过使用 GetPlanFactory 获取具体类的对象来生成账单,传递诸如 DOMESTICPLAN 或 COMMERCIALPLAN 或 INSTITUTIONALPLAN 等信息。
import java.io.*;
class GenerateBill {
public static void main(String args[]) throws IOException {
GetPlanFactory planFactory = new GetPlanFactory();
System.out.print("请输入要生成账单的计划名称: ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String planName = br.readLine();
System.out.print("请输入要计算账单的单位数量: ");
int units = Integer.parseInt(br.readLine());
Plan p = planFactory.getPlan(planName);
// 调用 getRate() 方法和 calculateBill() 方法
System.out.print(planName + " 的 " + units + " 单位的账单金额是: ");
p.getRate();
p.calculateBill(units);
}
} // GenerateBill 类结束