工厂方法是在设计模式中常用的一种模式,它属于设计模式的创造类型模式,主要用来创建对象。
定义: 定义一个创建对象的接口,但让实现这个接口的类来决定要实例化那个类,工厂方法让类的实例化延迟到子类进行。
类型: 创建型
使用场景
- 创建对象需要大量重复的代码
- 客户端(应用层)不依赖与产品类实例如何被创建、实现细节
- 一个类通过其子类来指定创建那个对象
优点
- 用户只需要关心所需产品的对应工厂,无序关心创建细节
- 加入新的产品符合开闭原则,提高扩展性
缺点
- 类的个数容易过多,增加复杂度
- 增加了系统的抽象性和理解难度
分析
工厂方法中一个工厂只生产一种产品,这样可以保证了工厂的唯一性,这点是和抽象工厂最大的区别。例如:冰箱工厂只能生产冰箱不能生产其他产品。我们可以通过提供一个或者一组重载方法来完成产品的定制。比如格力冰箱实现/继承冰箱方法抽象/接口类完成自己工厂的创建,美的冰箱同样也可以实现/继承冰箱抽象/接口类来完成自己工厂的创建。由于他们都是实现了统一的冰箱接口和冰箱方法类,那么客户端(应用层)只需要使用冰箱接口接口来根据自己需求获取自己需要的产品,并不需要知道具体的创建过程和细节。这也是编程中面向接口编程的思想。
案例
进入夏天正是冰箱售卖的好时节,供应商小李想采购一批冰箱售卖。那么他就需要知道冰箱的品牌和价格,而且他有可能采购不同厂商的冰箱。冰箱工厂会定义好的商品来生成。
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