Java工厂方法模式

工厂方法是在设计模式中常用的一种模式,它属于设计模式的创造类型模式,主要用来创建对象。

  • 定义: 定义一个创建对象的接口,但让实现这个接口的类来决定要实例化那个类,工厂方法让类的实例化延迟到子类进行。

  • 类型: 创建型

使用场景

  • 创建对象需要大量重复的代码
  • 客户端(应用层)不依赖与产品类实例如何被创建、实现细节
  • 一个类通过其子类来指定创建那个对象

优点

  • 用户只需要关心所需产品的对应工厂,无序关心创建细节
  • 加入新的产品符合开闭原则,提高扩展性

缺点

  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性和理解难度

分析

工厂方法中一个工厂只生产一种产品,这样可以保证了工厂的唯一性,这点是和抽象工厂最大的区别。例如:冰箱工厂只能生产冰箱不能生产其他产品。我们可以通过提供一个或者一组重载方法来完成产品的定制。比如格力冰箱实现/继承冰箱方法抽象/接口类完成自己工厂的创建,美的冰箱同样也可以实现/继承冰箱抽象/接口类来完成自己工厂的创建。由于他们都是实现了统一的冰箱接口和冰箱方法类,那么客户端(应用层)只需要使用冰箱接口接口来根据自己需求获取自己需要的产品,并不需要知道具体的创建过程和细节。这也是编程中面向接口编程的思想。

案例

进入夏天正是冰箱售卖的好时节,供应商小李想采购一批冰箱售卖。那么他就需要知道冰箱的品牌和价格,而且他有可能采购不同厂商的冰箱。冰箱工厂会定义好的商品来生成。

1. 定义产品即可和工厂接口

/**
 * 冰箱接口
 */
public interface IRefrigerator {
    //获取品牌名
    String getBrandName();

    //获取价格
    double getPrice();
}
/**
 * 冰箱工厂接口
 */
public interface IRefrigeratorFactory {

    IRefrigerator getIRefrigerator();
}

2. 产品实现类

/**
 * 海尔冰箱
 */
public class HaiErRefrigerator implements IRefrigerator {
    @Override
    public String getBrandName() {
        return "海尔冰箱";
    }

    @Override
    public double getPrice() {
        return 5999;
    }
}
/**
 * 美的冰箱
 */
public class MeiDiRefrigerator implements IRefrigerator {
    @Override
    public String getBrandName() {
        return "美的冰箱";
    }

    @Override
    public double getPrice() {
        return 2999;
    }
}
/**
 * 格力冰箱
 */
public class GeLiRefrigerator implements IRefrigerator {
    @Override
    public String getBrandName() {
        return "格力冰箱";
    }

    @Override
    public double getPrice() {
        return 3999;
    }
}

3. 工厂实现类

/**
 * 海尔冰箱工厂
 */
public class HaiErRefrigeratorFactory implements IRefrigeratorFactory {
    @Override
    public IRefrigerator getIRefrigerator() {
        return new HaiErRefrigerator();
    }
}
/**
 * 美的冰箱工厂
 */
public class MeiDiRefrigeratorFactory implements IRefrigeratorFactory {
    @Override
    public IRefrigerator getIRefrigerator() {
        return new MeiDiRefrigerator();
    }
}
/**
 * 格力冰箱工厂
 */
public class GeLiRefrigeratorFactory implements IRefrigeratorFactory {
    @Override
    public IRefrigerator getIRefrigerator() {
        return new GeLiRefrigerator();
    }
}

4. 测试类

/**
 * 测试类
 */
public class Test {

    public static void main(String[] args) {
        IRefrigeratorFactory refrigeratorFactory = new HaiErRefrigeratorFactory();
        IRefrigeratorFactory refrigeratorFactory2 = new GeLiRefrigeratorFactory();
        IRefrigeratorFactory refrigeratorFactory3 = new MeiDiRefrigeratorFactory();
        IRefrigerator refrigerator = refrigeratorFactory.getIRefrigerator();

        System.out.println("您购买了:" + refrigerator.getBrandName() + ",您需要支付:" + refrigerator.getPrice());
    }
}

5. 日志信息

您购买了:海尔冰箱,您需要支付:5999.0

UML图

简略版
细节版
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。