三种工厂有各自使用的场景, 任意一方都不能完全替代另一个。
简单工厂
根据枚举值来创建并返回对象,缺点就是每新增一种产品类型,就要维护这个类。这个工厂只有一个类,且只有一个简单的方法,所以叫简单工厂:
public class SimpleFactory {
public static Product makeProduct(int kind) {
switch (kind) {
case Const.PRODUCT_A:
return new ConcreteProductA();
case Const.PRODUCT_B:
return new ConcreteProductB();
}
return null;
}
}
工厂方法
简单工厂在添加新的产品时,仍然需要修改工厂代码,这不符合开闭原则。而工厂方法定义了一个用于创建对象的接口,让子类决定实例化哪个产品类对象。工厂方法模式让一个产品类的实例化延迟到其工厂的子类:
工厂方法共有四个角色:
// 抽象工厂
public interface FreeGoodsFactory {
IFreeGoods getInstance();
}
// 具体的工厂
public class DiscountFreeGoodsFactory implements FreeGoodsFactory {
@Override
public IFreeGoods getInstance() {
return new DiscountFreeGoods();
}
}
public class SmallGiftFreeGoodsFactory implements FreeGoodsFactory {
@Override
public IFreeGoods getInstance() {
return new SmallGiftFreeGoods();
}
}
// 使用工厂方法
/**
* 按照类型的不同发放商品
*/
public ResponseResult awardToUser(AwardInfo awardInfo){
FreeGoodsFactory freeGoodsFactory = null;
if(awardInfo.getAwardType() == 1){
freeGoodsFactory = new DiscountFreeGoodsFactory();
}else if(awardInfo.getAwardType() == 2){
freeGoodsFactory = new SmallGiftFreeGoodsFactory();
}
IFreeGoods freeGoods = freeGoodsFactory.getInstance();
ResponseResult result = freeGoods.sendFreeGoods(awardInfo);
return result;
}
工厂方法仍然耦合了获取工厂的代码,如果需要解耦这个获取工厂的方法,可以
抽象工厂
工厂方法模式只可以创建一类产品(电视机类,海尔电视机、海信电视机、TCL电视机),而抽象工厂则是创建一个产品族(海尔电视、海尔冰箱、海尔洗衣机,都是海尔一族;海信电视、海信冰箱、海信洗衣机都是海信一族...)。
代码如下:
抽象工厂
/**
* 抽象工厂: 在一个抽象工厂中可以声明多个工厂方法,用于创建不同类型的产品
* @author spikeCong
* @date 2022/9/15
**/
public interface AppliancesFactory {
AbstractTV createTV();
AbstractFreezer createFreezer();
}
具体工厂: 每一个具体工厂方法,可以返回一个特定的产品对象,而同一个具体工厂所创建的产品对象构成了一个产品族.
public class HairFactory implements AppliancesFactory {
@Override
public AbstractTV createTV() {
return new HairTV();
}
@Override
public AbstractFreezer createFreezer() {
return new HairFreezer();
}
}
public class HisenseFactory implements AppliancesFactory {
@Override
public AbstractTV createTV() {
return new HisenseTV();
}
@Override
public AbstractFreezer createFreezer() {
return new HisenseFreezer();
}
}
抽象产品
public interface AbstractFreezer {}
public interface AbstractTV {}
具体产品
public class HairFreezer implements AbstractFreezer {}
public class HisenseFreezer implements AbstractFreezer {}
public class HairTV implements AbstractTV {}
public class HisenseTV implements AbstractTV {}
客户端
public class Client {
private AbstractTV tv;
private AbstractFreezer freezer;
public Client(AppliancesFactory factory){
//在客户端看来就是使用抽象工厂来生产家电
this.tv = factory.createTV();
this.freezer = factory.createFreezer();
}
public AbstractTV getTv() {
return tv;
}
public void setTv(AbstractTV tv) {
this.tv = tv;
}
public AbstractFreezer getFreezer() {
return freezer;
}
public void setFreezer(AbstractFreezer freezer) {
this.freezer = freezer;
}
public static void main(String[] args) {
Client client = new Client(new HisenseFactory());
AbstractTV tv = client.getTv();
System.out.println(tv);
AbstractFreezer freezer = client.getFreezer();
System.out.println(freezer);
}
}