1. 有 H 和 T 两个文具厂:都能生产铅笔、橡皮两种文具,用抽象工厂模式设计一个程序模拟生产 H 牌的铅笔及橡皮。(思考:如果市场上需求其他品牌的铅笔及橡皮该怎么办?如果市场需求尺子该怎么办?)
    运用抽象工厂模式进行程序设计,设计文具厂的 UML 类图,根据类图编写源代码,调试程序并得到运行结果,进一步评估模式扩展性(如增加新的文具厂或者增加尺子产品),特别注意“配置文件+反射机制”的运用。

java设计模式-LMLPHP

以下是对上述 Java 代码的详细解析:

一、定义文具接口部分

  1. interface Pencilinterface Eraser分别定义了铅笔和橡皮的行为规范,即draw方法和erase方法。这使得不同品牌的铅笔和橡皮可以实现统一的接口,方便在程序中进行调用和管理。

二、实现 H 厂的文具部分

  1. class HPencil implements Pencil实现了Pencil接口,重写了draw方法,打印出特定的信息,表示正在使用 H 品牌的铅笔进行绘制。
  2. class HEraser implements Eraser实现了Eraser接口,重写了erase方法,打印出特定的信息,表示正在使用 H 品牌的橡皮进行擦除。

三、定义抽象工厂接口部分

  1. interface StationeryFactory定义了抽象工厂的规范,包含两个方法createPencilcreateEraser,分别用于创建铅笔和橡皮对象。

四、实现 H 厂的工厂类部分

  1. class HStationeryFactory implements StationeryFactory实现了抽象工厂接口,重写了createPencilcreateEraser方法,分别返回HPencilHEraser对象,实现了生产 H 品牌铅笔和橡皮的功能。

五、客户端代码测试部分

  1. main方法中,首先创建了一个HStationeryFactory对象,代表 H 厂的文具工厂。
  2. 然后通过工厂对象分别调用createPencilcreateEraser方法,创建了 H 品牌的铅笔和橡皮对象。
  3. 最后分别调用铅笔的draw方法和橡皮的erase方法,模拟使用这两种文具。

如果要增加新的文具厂(例如 T 厂):
java设计模式-LMLPHP

  1. 仿照 H 厂的实现方式,创建TPencilTEraserTStationeryFactory类,分别实现 T 品牌的铅笔、橡皮和工厂。
  2. 在客户端代码中,通过读取配置文件config.properties来动态选择要使用的工厂。配置文件中可以指定工厂的全限定类名,例如factory=HStationeryFactoryfactory=TStationeryFactory。程序通过反射机制根据配置文件中的类名创建相应的工厂对象。

如果要增加尺子产品:

  1. 定义尺子接口interface Ruler,并添加measure方法表示测量功能。
  2. 在抽象工厂接口StationeryFactory中添加createRuler方法。
  3. 在各个工厂类中实现createRuler方法,返回相应品牌的尺子对象。

具体操作步骤如下:

  1. 创建上述的 Java 类文件,并确保它们在同一个项目中。
  2. 创建一个config.properties文件,内容可以根据需要设置为factory=HStationeryFactoryfactory=TStationeryFactory等,以选择不同的工厂。
  3. 运行客户端代码Main类的main方法,程序将根据配置文件选择工厂并创建相应品牌的文具对象,然后调用它们的方法进行模拟使用。
    java设计模式-LMLPHP

这样,通过抽象工厂模式和配置文件+反射机制,可以方便地扩展程序以支持不同品牌的文具生产和新增的文具产品。

以下是使用 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=HStationeryFactoryfactory=TStationeryFactory
java设计模式-LMLPHP

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.");
    }
}

java设计模式-LMLPHP

09-28 11:06