设计模式-工厂模式

166 阅读3分钟

我们在平时的编程中,构建对象最常用的就是new对象,这种做法其实没什么不好,而实际上这也属于一种硬编码,每new一个对象,相当于调用者多知道了一个类,增加了类与类之间的联系,不利于程序的松耦合,其实构建过程可以被封装起来,工厂模式便是用于封装对象的设计模式。

简单工厂模型

直接new对象的方式相当于我们需要一个苹果时,我们需要知道苹果的构造方法,需要一个梨子时,我们需要知道梨子的构造方法。更好的实现方式是实现一个水果工厂,我们告诉工厂需要什么种类的水果,水果工厂便会将我们需要的水果制造出来给我们就可以了,这样我们就无需知道苹果,梨子是怎么构造出来的,只用和水果工厂打交道即可

水果工厂

public class FruitFactory {
    public Fruit create(String type){
        switch (type){
            case "苹果": return new Apple();
            case "梨子": return new Pear();
            default: throw new IllegalArgumentException("暂时没有这种水果");
        }
    }
}

调用者

public class User {
    private void eat(){
        FruitFactory fruitFactory = new FruitFactory();
        Fruit apple = fruitFactory.create("苹果");
        Fruit pear = fruitFactory.create("梨子");
        apple.eat();
        pear.eat();
    }
}

事实上,将构建过程封装的好处不仅可以降低耦合,如果某个产品构造方法相当复杂,使用工厂模式可以大大减少代码重复,比如,如果生产一个苹果需要苹果种子,阳光,水分

public class FruitFactory {
    public Fruit create(String type) {
        switch (type) {
            case "苹果":
                AppleSeed appleSeed = new AppleSeed();
                Sunlight sunlight = new Sunlight();
                Water water = new Water();
                return new Apple(appleSeed, sunlight, water);
            case "梨子":
                return new Pear();
            default:
                throw new IllegalArgumentException("暂时没有这种水果");
        }
    }
}

调用者的代码则完全不需要变化,而且调用者不需要在每次需要苹果时,自己去构建苹果种子,阳光和水分以获得苹果,苹果的生产过程在复杂,也只是工厂的事情,这就是封装的好处。

工厂模式一共有三种:

1)简单工厂模式

2)工厂方法模式

3)抽象工厂模式

工厂方法模式

工厂方法模式规定每个产品都有一个专属工厂,比如苹果有专属的苹果工厂,梨子有专属的梨子工厂

苹果工厂:

public class AppleFactory {
    public Fruit create(){
        AppleSeed appleSeed = new AppleSeed();
        Sunlight sunlight = new Sunlight();
        Water water = new Water();
        return new Apple(appleSeed, sunlight, water);
    }
}

梨子工厂:

public class PearFactory {
    public Fruit create(){
        return new Pear();
    }
}

调用者:

public class User {
    private void eat(){
        AppleFactory appleFactory = new AppleFactory();
        Fruit apple = appleFactory.create();
        PearFactory pearFactory = new PearFactory();
        Fruit pear = pearFactory.create();
        apple.eat();
        pear.eat();
    }
}

调用者无需知道苹果的生产细节,当生产过程需要修改时也无需更改调用端,同时,工厂方法模式解决了简单工厂模式的两个弊端

  • 当生产的产品种类越来越多时,工厂类不会变成超级类,工厂类会越来越多,保持灵活,就不会越来越大,变得臃肿,如果苹果的生产过程需要修改时,只需修改苹果工厂,梨子的生产过程需要修改时,只需要修改梨子工厂

  • 当需要生产新的产品时,无需更改既有的工厂,只需要添加新的工厂即可,保持了面向对象的可扩展性,符合开闭原则