设计模式——工厂方法模式(创建型模式)

引言

设计模式是我们开发中为了代码的可维护性和可复用性必须掌握的一项技能,设计模式分为23种,在讲解工厂方法模式之前,我们先来了解一下设计模式的原则以及分类。
设计模式原则
设计模式原则 英文缩写 意义
单一职责原则 SRP(Single responsibility principle) 就一个类而言应该只有一个引起它变化的原因
开放关闭原则 OCP(Open Closed Principle) 一个软件实体应该对扩展开放,对修改关闭
里氏替换原则 LSP liskov substitution principle 所有引用基类(父类)的地方必须能透明地使用其子类的对象
依赖倒置原则 DIP Dependency Inversion Principle 抽象不应该依赖于细节,细节应该依赖于抽象
接口隔离原则 ISP Interface Segregation Principle 使用多个专门的接口,而不使用单一的接口
迪米特法则 LOD Low Of Demeter 一个软件实体应当尽可能少地与其它实体发生相互作用
单一职责原则:是为了让我们的接口职责单一,代码高内聚低耦合。
开放关闭原则:表格中的软件实体可以指一个软件模块,或者一个由多个类组成的局部结构或者一个独立类。
里氏替换原则:是实现开闭原则的重要方式之一,可以扩展父类功能,但是不能改变父类功能,尽量不要重写父类方法。
依赖倒置原则:在变量类型声明,参数声明,方法返回值类型声明使用接口或者抽象类。
接口隔离原则:即接口大小要适中,太小会接口泛滥,太大将违背接口隔离原则。
迪米特法则:可以降低系统的耦合度,使类与类之间保持松散的耦合关系,当一个模块需要修改时候,需要尽量少地影响其它模块,这样扩展起来会比较容易。
设计模式分类
类别 设计模式
创建型模式(五种) 工厂方法模式 抽象工厂模式 单例模式 建造者模式 原型模式
结构型模式(七种) 适配器模式 装饰者模式 代理模式 外观模式 桥接模式 组合模式 享元模式
行为型模式(十一种) 策略模式 模板方法模式 观察者模式 迭代器模式 责任链模式 命令模式 备忘录模式 状态模式 访问者模式 中介者模式 解释器模式
工厂方法模式概述:
  • 普通工厂方法模式:
    有大量的产品需要创建,并且有共同的接口时候,可以通过工厂方法模式进行创建。
    这里我们创建一个创建一个统一的接口Animal
    public interface Animal { void eat(); }

    再创建两个动物类,DogCat:
    public class Cat implements Animal { @Override public void eat() { System.out.println("cat eat fish"); } } public class Dog implements Animal { @Override public void eat() { System.out.println("dog eat meat"); } }

    这个时候如果我们想要创建CatDog的实例, 用普通工厂方法创建的工厂类代码如下:
    public class AnimalFactory1 { /** * 普通工厂方法模式 * @param animalName * @return */ public Animal getAnimal(String animalName) { if ("cat".equals(animalName)) { return new Cat(); } else if ("dog".equals(animalName)) { return new Dog(); } else { throw new IllegalArgumentException("don't have this animal"); } } }

    测试code和结果如下:
    public class Test { public static void main(String[] args) { System.out.println("普通工厂模式----------"); AnimalFactory1 factory = new AnimalFactory1(); Animal cat = factory.getAnimal("cat"); cat.eat(); Animal dog = factory.getAnimal("dog"); dog.eat(); System.out.println("--------------------"); } }

    普通工厂模式---------- cat eat fish dog eat meat --------------------

    但是这种设计模式有一个问题就是参数,每次我们创建一个对象都需要输入一个字符串,这样有输入错误的风险,所以接下来我们看多个工厂方法模式。
    • 多个工厂方法模式
      还是上面的CatDog类,我们修改一些工厂类,将字符串参数去掉,如下:
    public class AnimalFactory2 { /** * 多个方法工厂模式 * 直接定义为接口获取实例,避免字符串出错 * @return */ public Animal getCat() { return new Cat(); }public Animal getDog() { return new Dog(); } }

    这样的话我们的测试代码就变成了:
    public class Test { public static void main(String[] args) { System.out.println("多个工厂方法模式--------------"); AnimalFactory2 factory2 = new AnimalFactory2(); factory2.getCat().eat(); factory2.getDog().eat(); System.out.println("--------------------"); } }

    测试结果如下:
    多个工厂方法模式-------------- cat eat fish dog eat meat --------------------

  • 静态工厂方法模式:
    上面的模式需要new关键字来获取工厂类,下面我们讲解一下静态工厂方法模式,这种模式用处比较普遍(Executors中使用的就是这种模式),还是上面的CatDog类,我们修改工厂类加上关键字static,变为如下:
public class AnimalFactory3 { /** * 静态工厂方法模式 * 直接定义为接口获取实例,避免字符串出错 * @return */ public static Animal getCat() { return new Cat(); }public static Animal getDog() { return new Dog(); } }

这样的好处是显而易见的,使用方便并且不会出错,测试代码如下:
public class Test { public static void main(String[] args) { System.out.println("静态工厂方法模式-----------"); AnimalFactory3.getCat().eat(); AnimalFactory3.getDog().eat(); System.out.println("--------------------"); } }

【设计模式——工厂方法模式(创建型模式)】测试结果是:
静态工厂方法模式----------- cat eat fish dog eat meat --------------------

工厂模式比较简单,工作中也比较常见,大家要认真学习,欢迎留言区交流。

    推荐阅读