栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

设计模式:工厂模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式:工厂模式

工厂模式绕不开的3种:简单工厂、工厂方法和抽象工厂,属于创建型模式,其中简单工厂不在GoF23种设计模式之列,但一并说了。

简单工厂模式

最近太热了,就用空调和冰箱来举例吧。

空调品牌非常多,如美的、长虹、格力、海尔等等,现在需要生产这些空调,由于生产过程非常复杂,对于客户端并不需要知道如何生产,只要拿到最终产品即可,于是就有了下面这段代码:

public class SimpleFactory {
    public AirConditioner produce(String brand) {
        switch (brand) {
            case "Haier":
                return new HaierAirConditioner();
            case "Midea":
                return new MideaAirConditioner();
            default:
                return null;
        }
    }
}

空调的接口:

public interface AirConditioner {
    void print();
}

具体的空调产品:美的空调

public class MideaAirConditioner implements AirConditioner {
    @Override
    public void print() {
        System.out.println("美的空调");
    }
}

海尔空调:

public class HaierAirConditioner implements AirConditioner {
    @Override
    public void print() {
        System.out.println("海尔空调");
    }
}

下面是测试类:

public class SimpleFactoryTest {
    public static void main(String[] args) {
        //创建工厂
        SimpleFactory simpleFactory = new SimpleFactory();
        //生产美的空调
        AirConditioner midea = simpleFactory.produce("Midea");
        midea.print();
        //生产海尔空调
        AirConditioner haier = simpleFactory.produce("Haier");
        haier.print();
    }
}

//运行结果:
//美的空调
//海尔空调

以上就是简单工厂的实现,非常简单,可以把一些重复复杂的操作封装起来,让使用者不必关心产品是怎么生产的,只要知道想要什么就行(例如品牌作为参数传入),但从中我们也发现不少问题,例如现在需要增加一个品牌,比如格力空调,那么就需要去修改工厂类,这不符合开闭原则。

工厂方法模式

工厂方法的核心就是让父类定义标准,由子类去实现具体要生产哪种商品。

还是上面空调的例子,这时我们需要定义一个空调工厂接口:

public interface IAirConditionerFactory {
    AirConditioner produce();
}

现在需要生产海尔空调,就创建一个海尔空调的工厂:

public class HaierAirConditionerFactory implements IAirConditionerFactory {
    @Override
    public AirConditioner produce() {
        return new HaierAirConditioner();
    }
}

需要生产美的空调,就创建一个美的空调的工厂:

public class MideaAirConditionerFactory implements IAirConditionerFactory {
    @Override
    public AirConditioner produce() {
        return new MideaAirConditioner();
    }
}

下面是测试类:

public class FactoryMethodTest {
    public static void main(String[] args) {
        //创建海尔空调工厂
        IAirConditionerFactory haierFactory = new HaierAirConditionerFactory();
        //生产海尔空调
        AirConditioner haier = haierFactory.produce();
        haier.print();
        //创建美的空调工厂
        IAirConditionerFactory mideaFactory = new MideaAirConditionerFactory();
        //生产美的空调
        AirConditioner midea = mideaFactory.produce();
        midea.print();
    }
}

这种方式的好处显而易见,如果我还需要增加格力空调的生产,只需要增加一个格力空调工厂类和一个格力空调产品类即可,对原有代码没有任何影响,符合开闭原则。有优点自然也会有缺点,对于比较复杂的系统,这种方法可能会产生非常多的类,显得臃肿,后期不便于维护,有利有弊,看怎么取舍了。

抽象工厂模式

先引入两个概念:产品族和产品等级结构。

产品族:同一个工厂生产的满足不同客户个性化需求的一组相关产品。如海尔生产的空调、冰箱。

产品等级结构:产品继承结构,如我们上面的海尔空调、美的空调就是空调的一个产品等级结构。

接下来,需要生产空调和冰箱,空调还是用上面的类,接下来创建冰箱的接口:

public interface Fridge {
    void print();
}

海尔冰箱

public class HaierFridge implements Fridge {
    @Override
    public void print() {
        System.out.println("海尔冰箱");
    }
}

美的冰箱

public class MideaFridge implements Fridge {
    @Override
    public void print() {
        System.out.println("美的冰箱");
    }
}

工厂接口,定义生产空调和冰箱的方法

public interface IFactory {
    AirConditioner produceAirConditioner();
    Fridge produceFridge();
}

海尔工厂

public class HaierFactory implements IFactory {
    @Override
    public AirConditioner produceAirConditioner() {
        return new HaierAirConditioner();
    }

    @Override
    public Fridge produceFridge() {
        return new HaierFridge();
    }
}

美的工厂

public class MideaFactory implements IFactory {
    @Override
    public AirConditioner produceAirConditioner() {
        return new MideaAirConditioner();
    }

    @Override
    public Fridge produceFridge() {
        return new MideaFridge();
    }
}

下面是测试类:

public class AbstractFactoryTest {
    public static void main(String[] args) {
        //创建海尔工厂
        IFactory haierFactory = new HaierFactory();
        //生产海尔冰箱
        Fridge haierFridge = haierFactory.produceFridge();
        haierFridge.print();
        //生产海尔空调
        AirConditioner haierAirConditioner = haierFactory.produceAirConditioner();
        haierAirConditioner.print();

        //创建美的工厂
        IFactory mideaFactory = new MideaFactory();
        //生产美的空调
        mideaFactory.produceAirConditioner().print();
        //生产美的冰箱
        mideaFactory.produceFridge().print();
    }
}

好了,继续思考一下工厂方法那个扩展,现在需要生产格力空调和格力冰箱,我们只需要创建一个格力工厂,和相应的格力空调、格力冰箱类即可,也符合开闭原则,但这是在产品等级结构的扩展,完全没有问题,如果是产品族的扩展呢?那问题就大了,假设现在需要增加一个洗衣机,那怎么办,是不是就得修改IFactory了,而修改了IFactory,那么导致其他实现类都得修改,影响巨大。所以抽象工厂模式在产品族的扩展就不符合开闭原则了。

学到这里,我就有个疑问了,工厂方法和抽象工厂之间的区别是什么呢?下面就说说自己的理解:

1.简单工厂就只有一个工厂类,通过传入的参数决定生产哪种商品,有大量的if-else。

2.工厂方法可以有多个工厂,但只针对一种产品,父类定义标准,由子类决定具体生产哪种商品。

3.抽象工厂可以有多个工厂,多种产品,一个工厂可以生产多种产品。

具体使用场景:

1.有大量复杂的创建操作而不关心创建细节;

2.可扩展的内部组件

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1027958.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号