(三)构建型模式-工厂方法模式

itmahy
itmahy
发布于 2024-01-19 / 30 阅读
0
0

(三)构建型模式-工厂方法模式

工厂模式

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

简单工厂模式

/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-07 14:54
 * @Description: 动物的实体类
 */
public class Animal {
​
    public String sleep(){
        return null;
    }
}
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-07 14:52
 * @Description: 猫的实体类
 */
public class Cat extends Animal {
    
    @Override
    public String sleep(){
        return "猫在睡觉";
    }
}
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-07 14:51
 * @Description: 狗的实体类
 */
public class Dog extends Animal{
​
    @Override
    public String sleep(){
        return "狗在睡觉";
    }
}
​
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-07 14:53
 * @Description: 工厂类
 */
public class AnimalFactory {
​
    public Animal create(String action){
        switch (action){
            case "猫": return new Cat();
            case "狗": return new Dog();
            default: throw new IllegalArgumentException("没有这种动物");
        }
    }
}
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-07 14:02
 * @Description: 测试简单工厂模式
 */
public class Test001 {
​
    public static void main(String[] args) {
       AnimalFactory factory = new AnimalFactory();
        Animal cat = factory.create("猫");
        Animal dog = factory.create("狗");
​
        String catSleep = cat.sleep();
        String dogSleep = dog.sleep();
        System.out.println(catSleep); //猫在睡觉
        System.out.println(dogSleep); //狗在睡觉
    }
}

调用者完全不用关系猫跟狗中代码的变化,如果新增一种动物,调用者只需要根据名称调用即可,不用管它是怎么生成的,或者怎么生长的。

注:在 《设计模式》一书中,简单工厂模式被划分为工厂方法模式的一种特例,没有单独被列出来。

总而言之,简单工厂模式就是让一个工厂类承担构建所有对象的职责。调用者需要什么产品,让工厂生产出来即可。它的弊端也显而易见:

  • 一是如果需要生产的产品过多,此模式会导致工厂类过于庞大,承担过多的职责,变成超级类。当苹果生产过程需要修改时,要来修改此工厂。梨子生产过程需要修改时,也要来修改此工厂。也就是说这个类不止一个引起修改的原因。违背了单一职责原则。

  • 二是当要生产新的产品时,必须在工厂类中添加新的分支。而开闭原则告诉我们:类应该对修改封闭。我们希望在添加新功能时,只需增加新的类,而不是修改既有的类,所以这就违背了开闭原则。

工程方法模式

为了解决简单工厂模式的这两个弊端,工厂方法模式应运而生,它规定每个产品都有一个专属工厂。

实体类照样是上面的

/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-07 15:10
 * @Description: 狗的工厂类方法
 */
public class DogFactory {
​
    public Animal create(){
        return new Dog();
    }
}
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-07 15:11
 * @Description: 猫的工程类方法
 */
public class CatFactory {
​
    public Animal create(){
        return  new Cat();
    }
}
/**
 * @Author: mahy
 * @Contact: [email protected]
 * @Date: 2022-03-07 14:02
 * @Description: 测试工厂类方法模式
 */
public class Test001 {
​
    public static void main(String[] args) {
        DogFactory factory = new DogFactory();
        Dog dog = (Dog) factory.create();
        CatFactory factory1 = new CatFactory();
        Cat cat = (Cat) factory1.create();
        String dogSleep = dog.sleep();
        String catSleep = cat.sleep();
        System.out.println(dogSleep); //狗在睡觉
        System.out.println(catSleep); //猫在睡觉
    }
}

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

  • 当生产的产品种类越来越多时,工厂类不会变成超级类。工厂类会越来越多,保持灵活。不会越来越大、变得臃肿。如果狗或者猫的生产过程需要修改时,只需修改狗工厂。猫的生产过程需要修改时,只需修改猫工厂。符合单一职责原则。

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



评论