- 有 H 和 T 两个文具厂:都能生产铅笔、橡皮两种文具,用抽象工厂模式设计一个程序模拟生产 H 牌的铅笔及橡皮。(思考:如果市场上需求其他品牌的铅笔及橡皮该怎么办?如果市场需求尺子该怎么办?)
运用抽象工厂模式进行程序设计,设计文具厂的 UML 类图,根据类图编写源代码,调试程序并得到运行结果,进一步评估模式扩展性(如增加新的文具厂或者增加尺子产品),特别注意“配置文件+反射机制”的运用。
以下是对上述 Java 代码的详细解析:
一、定义文具接口部分
interface Pencil
和interface Eraser
分别定义了铅笔和橡皮的行为规范,即draw
方法和erase
方法。这使得不同品牌的铅笔和橡皮可以实现统一的接口,方便在程序中进行调用和管理。
二、实现 H 厂的文具部分
class HPencil implements Pencil
实现了Pencil
接口,重写了draw
方法,打印出特定的信息,表示正在使用 H 品牌的铅笔进行绘制。class HEraser implements Eraser
实现了Eraser
接口,重写了erase
方法,打印出特定的信息,表示正在使用 H 品牌的橡皮进行擦除。
三、定义抽象工厂接口部分
interface StationeryFactory
定义了抽象工厂的规范,包含两个方法createPencil
和createEraser
,分别用于创建铅笔和橡皮对象。
四、实现 H 厂的工厂类部分
class HStationeryFactory implements StationeryFactory
实现了抽象工厂接口,重写了createPencil
和createEraser
方法,分别返回HPencil
和HEraser
对象,实现了生产 H 品牌铅笔和橡皮的功能。
五、客户端代码测试部分
- 在
main
方法中,首先创建了一个HStationeryFactory
对象,代表 H 厂的文具工厂。 - 然后通过工厂对象分别调用
createPencil
和createEraser
方法,创建了 H 品牌的铅笔和橡皮对象。 - 最后分别调用铅笔的
draw
方法和橡皮的erase
方法,模拟使用这两种文具。
如果要增加新的文具厂(例如 T 厂):
- 仿照 H 厂的实现方式,创建
TPencil
、TEraser
和TStationeryFactory
类,分别实现 T 品牌的铅笔、橡皮和工厂。 - 在客户端代码中,通过读取配置文件
config.properties
来动态选择要使用的工厂。配置文件中可以指定工厂的全限定类名,例如factory=HStationeryFactory
或factory=TStationeryFactory
。程序通过反射机制根据配置文件中的类名创建相应的工厂对象。
如果要增加尺子产品:
- 定义尺子接口
interface Ruler
,并添加measure
方法表示测量功能。 - 在抽象工厂接口
StationeryFactory
中添加createRuler
方法。 - 在各个工厂类中实现
createRuler
方法,返回相应品牌的尺子对象。
具体操作步骤如下:
- 创建上述的 Java 类文件,并确保它们在同一个项目中。
- 创建一个
config.properties
文件,内容可以根据需要设置为factory=HStationeryFactory
或factory=TStationeryFactory
等,以选择不同的工厂。 - 运行客户端代码
Main
类的main
方法,程序将根据配置文件选择工厂并创建相应品牌的文具对象,然后调用它们的方法进行模拟使用。
这样,通过抽象工厂模式和配置文件+反射机制,可以方便地扩展程序以支持不同品牌的文具生产和新增的文具产品。
以下是使用 Java 实现抽象工厂模式来模拟文具生产的示例代码:
一、定义文具接口
interface Pencil {
void draw();
}
interface Eraser {
void erase();
}
二、实现 H 厂的文具
class HPencil implements Pencil {
@Override
public void draw() {
System.out.println("Drawing with H brand pencil.");
}
}
class HEraser implements Eraser {
@Override
public void erase() {
System.out.println("Erasing with H brand eraser.");
}
}
三、定义抽象工厂接口
interface StationeryFactory {
Pencil createPencil();
Eraser createEraser();
}
四、实现 H 厂的工厂类
class HStationeryFactory implements StationeryFactory {
@Override
public Pencil createPencil() {
return new HPencil();
}
@Override
public Eraser createEraser() {
return new HEraser();
}
}
五、客户端代码测试
public class Main {
public static void main(String[] args) {
StationeryFactory factory = new HStationeryFactory();
Pencil pencil = factory.createPencil();
Eraser eraser = factory.createEraser();
pencil.draw();
eraser.erase();
}
}
如果要增加新的文具厂或者增加尺子产品,可以按照以下方式扩展:
1. 增加新的文具厂(例如 T 厂)
class TPencil implements Pencil {
@Override
public void draw() {
System.out.println("Drawing with T brand pencil.");
}
}
class TEraser implements Eraser {
@Override
public void erase() {
System.out.println("Erasing with T brand eraser.");
}
}
class TStationeryFactory implements StationeryFactory {
@Override
public Pencil createPencil() {
return new TPencil();
}
@Override
public Eraser createEraser() {
return new TEraser();
}
}
在客户端代码中,可以根据配置文件动态选择工厂:
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class Main {
public static void main(String[] args) {
Properties props = new Properties();
try (FileInputStream fis = new FileInputStream("config.properties")) {
props.load(fis);
String factoryName = props.getProperty("factory");
StationeryFactory factory;
try {
factory = (StationeryFactory) Class.forName(factoryName).newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
Pencil pencil = factory.createPencil();
Eraser eraser = factory.createEraser();
pencil.draw();
eraser.erase();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在config.properties
配置文件中可以指定要使用的工厂,例如:factory=HStationeryFactory
或factory=TStationeryFactory
。
2. 增加尺子产品
首先定义尺子接口:
interface Ruler {
void measure();
}
然后在每个工厂中添加创建尺子的方法:
interface StationeryFactory {
Pencil createPencil();
Eraser createEraser();
Ruler createRuler();
}
class HStationeryFactory implements StationeryFactory {
//... existing methods
@Override
public Ruler createRuler() {
return new HRuler();
}
}
class HRuler implements Ruler {
@Override
public void measure() {
System.out.println("Measuring with H brand ruler.");
}
}
class TStationeryFactory implements StationeryFactory {
//... existing methods
@Override
public Ruler createRuler() {
return new TRuler();
}
}
class TRuler implements Ruler {
@Override
public void measure() {
System.out.println("Measuring with T brand ruler.");
}
}