- 有 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 {@Overridepublic void draw() {System.out.println("Drawing with H brand pencil.");}
}class HEraser implements Eraser {@Overridepublic void erase() {System.out.println("Erasing with H brand eraser.");}
}
三、定义抽象工厂接口
interface StationeryFactory {Pencil createPencil();Eraser createEraser();
}
四、实现 H 厂的工厂类
class HStationeryFactory implements StationeryFactory {@Overridepublic Pencil createPencil() {return new HPencil();}@Overridepublic 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 {@Overridepublic void draw() {System.out.println("Drawing with T brand pencil.");}
}class TEraser implements Eraser {@Overridepublic void erase() {System.out.println("Erasing with T brand eraser.");}
}class TStationeryFactory implements StationeryFactory {@Overridepublic Pencil createPencil() {return new TPencil();}@Overridepublic 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@Overridepublic Ruler createRuler() {return new HRuler();}
}class HRuler implements Ruler {@Overridepublic void measure() {System.out.println("Measuring with H brand ruler.");}
}class TStationeryFactory implements StationeryFactory {//... existing methods@Overridepublic Ruler createRuler() {return new TRuler();}
}class TRuler implements Ruler {@Overridepublic void measure() {System.out.println("Measuring with T brand ruler.");}
}