重学设计模式之工厂模式与抽象工厂模式

404 阅读3分钟

工厂模式

定义

工厂模式是定义一个用于创建对象的接口,让子类决定实例化那个类。

使用场景

  1. 任何需要生成复杂对象的地方,都可以使用工厂模式。
  2. 在不同条件下创建不同实例。

代码实现

以下为使用工厂模式实现数据存储业务。

  • 抽象产品类定义操作方法
public abstract class DataHandler {

    public abstract void add(String id, String name);

    public abstract void delete(String id);

    public abstract void update(String id, String name);

    public abstract String query(String id);
}
  • 三种不同存储方式(文件、xml、数据库)的代码实现。
public class FileHandler extends DataHandler{
    @Override
    public void add(String id, String name) {

    }

    @Override
    public void delete(String id) {

    }

    @Override
    public void update(String id, String name) {

    }

    @Override
    public String query(String id) {
        return "FileHandler";
    }
}
public class XmlHandler extends DataHandler{
    @Override
    public void add(String id, String name) {

    }

    @Override
    public void delete(String id) {

    }

    @Override
    public void update(String id, String name) {

    }

    @Override
    public String query(String id) {
        return "XmlHandler";
    }
}
public class DBHandler extends DataHandler {
    @Override
    public void add(String id, String name) {

    }

    @Override
    public void delete(String id) {

    }

    @Override
    public void update(String id, String name) {

    }

    @Override
    public String query(String id) {
        return "DBHandler";
    }
}
  • 工厂类
public class DataFactory {

    public static <T extends DataHandler> T getDataHandler(Class<T> tClass) {
        DataHandler handler = null;
        try {
            handler = (DataHandler) Class.forName(tClass.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) handler;
    }
}
  • 工厂模式的使用
public class DataHandlerTest {

    @Test
    public void testFactory() {
        FileHandler fileHandler = DataFactory.getDataHandler(FileHandler.class);
        System.out.println("FileHandler query result =  " + fileHandler.query("Test"));

        XmlHandler xmlHandler = DataFactory.getDataHandler(XmlHandler.class);
        System.out.println("XmlHandler query result =   " + xmlHandler.query("Test"));

        DBHandler dbHandler = DataFactory.getDataHandler(DBHandler.class);
        System.out.println("FileHandler query result =  " + dbHandler.query("Test"));
    }
}

FileHandler query result =  FileHandler
XmlHandler query result =   XmlHandler
FileHandler query result =  DBHandler

抽象工厂模式

定义

抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需制定对象的具体类。对象的创建最终由具体工厂完成。

使用场景

  1. 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
  2. 系统中有多于一个的产品族,而每次只使用其中某一产品族。
  3. 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
  4. 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

抽象工厂与工厂模式的区别

抽象工厂中每个工厂可以创建多种类的产品,而工厂模式中只能创建一类产品。

代码实现

  • 抽象工厂类:定义具体工厂的通用接口。
  • 具体工厂类:通过使用不同目标产品的方法创建不同具体产品类的实例。
  • 抽象产品族类:定义抽象产品类的公共接口。
  • 抽象产品类:继承抽象产品族类,定义具体产品类的公共接口。
  • 具体产品类:继承抽象产品类,定义创建对应具体产品实例的方法。

现有成衣公司需要生成时尚和古典风格的外套T恤。

  1. 首先定义抽象成衣族类 Clothes,内涵成衣的公共接口 show()
public interface Clothes {
    void show();
}
  1. 分别定义外套和T恤的抽象产品类
public abstract class CoatClothes implements Clothes {}

public abstract class TShirtClothes implements Clothes{ }
  1. 定义具体的不同风格和类型的成衣类
public class StylishCoat extends CoatClothes {
    @Override
    public void show() {
        System.out.println("生成时尚的外套");
    }
}

public class ClassicCoat extends CoatClothes {
    @Override
    public void show() {
        System.out.println("生成古典的外套");
    }
}

public class StylishTShirt extends TShirtClothes {
    @Override
    public void show() {
        System.out.println("生成时尚的T恤");
    }
}

public class ClassicTShirt extends TShirtClothes {
    @Override
    public void show() {
        System.out.println("生成古典的T恤");
    }
}
  1. 定义外套和T恤的具体工厂类来生产不同风格的外套和T恤
public class CoatFactory extends AbstractFactory {

    @Override
    public Clothes stylish() {
        return new StylishCoat();
    }

    @Override
    public Clothes classic() {
        return new ClassicCoat();
    }
}

public class TShirtFactory extends AbstractFactory {

    @Override
    public Clothes stylish() {
        return new StylishTShirt();
    }

    @Override
    public Clothes classic() {
        return new ClassicTShirt();
    }
}
  1. 启动工厂生产成衣
public class AbstractFactoryTest {

    @Test
    public void clothes() {
        CoatFactory coatFactory = new CoatFactory();
        coatFactory.stylish().show();
        coatFactory.classic().show();

        TShirtFactory tShirtFactory = new TShirtFactory();
        tShirtFactory.stylish().show();
        tShirtFactory.classic().show();
    }
}

生成时尚的外套
生成古典的外套
生成时尚的T恤
生成古典的T恤