Java 设计模式 简单工厂 工厂模式 抽象工厂

工厂模式,实际上也会根据业务情景不同会有不同的实现方式。一般分为3种。简单工厂,工厂模式和抽象工厂。顾名思义,这三种从简单到抽象,名称越来越高大上,实现方式肯定是越来越复杂

结论1:三种工厂的实现越来越复杂

简单工厂

public class Factory
{
    // 定义产品编号
    public int prodNo;

    // 构造工厂时告知工厂产品标识
    public Factory(int prodNo)
    {
        this.prodNo = prodNo;
    }

    public IProduct GetProduct()
    {
        // 根据产品标识生产产品
        switch (prodNo) 
        {
            case prodNo1:
                return new ProductA();
                break;
            case prodNo2:
                return new ProductB();
                break;
            default:
                ...
        }
}
}


// 产品A
class ProductA implements IProduct
{
    //产品属性
    //......
}

//产品B
class ProductB implements IProduct
{
    //产品属性
    //......
}

//产品接口
public interface IProduct
{
    //产品方法
    //......
}

简单工厂的问题就在于swich case(或者if else)。每当新增一种产品时,你都需要去维护工厂中的判断语句,造成该工厂类不断增长,各种判断挤在一起,给扩展和维护带来麻烦。产品和工厂没有实现完全解耦,绑定在一起

结论2:简单工厂通过构造时传入的标识来生产产品,不同产品都在同一个工厂中生产,这种判断会随着产品的增加而增加,给扩展和维护带来麻烦

工厂模式

// 工厂接口
interface IFactory 
{
    IProduct GetProduct();
}

// A工厂类
class FactoryA implements IFactory
{
    IProduct productA;
    public FactoryA()
    {
        this.productA = new ProductA();
    }

    public IProduct GetProduct() //A工厂生产A产品
    {
        return this.productA;
    }
}

//B工厂类
class FactoryB implements IFactory
{
    IProduct productB;
    public FactoryB()
    {
        this.productB = new ProductB();
    }

    public IProduct GetProduct() //B工厂生产B产品
    {
        return this.productB;
    }
}

//产品接口
interface IProduct
{
    //产品方法
    //......
}

//产品A
class ProductA implements IProduct
{
    //产品属性
    //......
}

//产品B
class ProductB implements IProduct
{
    //产品属性
    //......
}

在工厂模式中,已经将工厂类分开,不再将所有产品在同一工厂中生产,解决了简单工厂中不断增加的switch case的问题。如再新增一个C产品,那么只需写一个C工厂和C产品,在调用时用C工厂生产C产品即可,A和B工厂和产品完全不受影响

结论3:工厂模式无法解决产品族和产品等级结构的问题

抽象工厂

实现不同的产品族,并且实现产品等级结构


// 工厂接口,即抽象工厂
interface IFactory
{
    IFridge CreateFridge();
    IAirCondition CreateAirCondition();
}

// 三星的工厂,生产三星的产品族
class SamsungFactory implements IFactory
{
    public IAirCondition CreateAirCondition()
    {
        // 三星的工厂生产三星的空调
        return new SamsungAirCondition(); 
    }
    public IFridge CreateFridge()
    {
        // 三星的工厂生产三星的冰箱
        return new SamsungFridge(); 
    }
}

// 格力的工厂,生产格力的产品族
class GreeFactry implements IFactory
{
    public IAirCondition CreateAirCondition()
    {
        // 格力的工厂生产格力的空调
        return new GreeAirCondition(); 
    }
    public IFridge CreateFridge()
    {
        // 格力的工厂生产格力的冰箱
        return new GreeFridge(); 
    }
}

// 冰箱产品接口
interface IFridge
{
    // 冰箱产品接口
    // 冰箱的action
}

// 空调接口
interface IAirCondition
{
    // 空调产品接口
    // 空调的action
}

// 三星的冰箱
public class SamsungFridge implements IFridge
{
    // 三星冰箱的action和property
}

// 格力的冰箱
public class GreeFridge : IFridge
{
    // 格力冰箱的action和property
}

// 三星的空调
public class SamsungAirCondition implements IAirCondition
{
    // 三星空调的action和property
}

// 格力的空调
public class GreeAirCondition implements IAirCondition
{
    / /格力空调的action和property
}

在工厂模式中,一个工厂生产一个产品,所有的具体产品是由同一个抽象产品派生的,不存在产品等级结构和产品族的概念;而在抽象工厂中,同一个等级的产品是派生于一个抽象产品(即产品接口),一个抽象工厂派生不同的具体工厂,每个具体工厂生产自己的产品族(包含不同产品等级)

结论4:工厂模式中,一个工厂生产一个产品,所有产品派生于同一个抽象产品(或产品接口);而抽象工厂模式中,一个工厂生产多个产品,它们是一个产品族,不同的产品族的产品派生于不同的抽象产品(或产品接口)

三种工厂模式关键点

  • 三种工厂的实现是越来越复杂的

  • 简单工厂通过构造时传入的标识来生产产品,不同产品都在同一个工厂中生产,这种判断会随着产品的增加而增加,给扩展和维护带来麻烦

  • 工厂模式无法解决产品族和产品等级结构的问题

  • 抽象工厂模式中,一个工厂生产多个产品,它们是一个产品族,不同的产品族的产品派生于不同的抽象产品(或产品接口)

工厂模式问答

  • 在上面的代码中,都使用了接口来表达抽象工厂或者抽象产品,那么可以用抽象类吗?有何区别?

从功能上说,完全可以,甚至可以用接口来定义行为,用抽象类来抽象属性。抽象类更加偏向于属性的抽象,而用接口更加偏向行为的规范与统一。使用接口有更好的可扩展性和可维护性,更加灵活实现松散耦合,所以编程原则中有一条是针对接口编程而不是针对类编程

  • 到底何时应该用工厂模式

根据具体业务需求。不要认为简单工厂是用switch case就觉得一无是处,也不要觉得抽象工厂比较高大上就到处套。我们使用设计模式是为了解决问题而不是炫技,所以根据三种工厂模式的特质,以及对未来扩展的预期,来确定使用哪种工厂模式

  • 说说你在项目中工厂模式的应用

一个旅游产品的B2B网站,根据不同类型的业务形态,产品也是不同的,有国内跟团,出境跟团,国内自由行,出境自由行,邮轮五种产品,并且后面可能还会有门票,酒店,机票等等产品,其中有些联系也有些区别

    原文作者:设计模式
    原文地址: https://segmentfault.com/a/1190000008140135
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞