工厂方法模式
简介
工厂方法模式(Factory Method)是一种常用的对象创建型设计模式,此模式的核心精神是封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂;具体工厂;抽象产品;具体产品。
工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。
工厂方法模式对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不再负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。
使用场景
第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。Java Collection中的iterator() 方法即属于这种情况。
第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。
类图
实现方式
抽象产品
package com.rabbit.pattern.factory_method;
/**
* 抽象动物接口
* Created by vip on 2018/2/8.
*/
public interface Animal {
void eat();//吃
void say();//说
}
具体产品
package com.rabbit.pattern.factory_method;
/**
* 具体动物类
* Created by vip on 2018/2/8.
*/
public class Cat implements Animal {
@Override
public void eat() {
System.out.println("我是猫,我吃鱼");
}
@Override
public void say() {
System.out.println("我是猫,喵喵喵");
}
}
package com.rabbit.pattern.factory_method;
/**
* 具体动物类
* Created by vip on 2018/2/8.
*/
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("我是狗,我吃骨头");
}
@Override
public void say() {
System.out.println("我是狗,汪汪汪");
}
}
抽象工厂
package com.rabbit.pattern.factory_method;
/**
* 抽象的动物工厂接口
* Created by vip on 2018/2/8.
*/
public interface AnimalFactory {
Animal newInstance();
}
具体工厂
package com.rabbit.pattern.factory_method;
/**
* 具体工厂类
* Created by vip on 2018/2/8.
*/
public class CatFactory implements AnimalFactory {
@Override
public Animal newInstance() {
return new Cat();
}
}
package com.rabbit.pattern.factory_method;
/**
* 具体工厂类
* Created by vip on 2018/2/8.
*/
public class DogFactory implements AnimalFactory {
@Override
public Animal newInstance() {
return new Dog();
}
}
总结
工厂方法模式对于工厂模式(不了解工厂模式的可以去链接的地址学习:http://blog.csdn.net/sinat_32366329/article/details/79285248)最大的好处就是迎合了“开闭原则”,假如我们添加一个牛的具体类,对于工厂模式的普通逻辑方式和多静态方法方式的工厂模式,我们需要添加case分支判断或者添加一个静态的类,这样就违背了“开闭原则”。但是如果使用工厂方法模式,我们添加了牛的具体类,只需要另外添加一个牛的具体工厂类就可以了,这样就符合了“开闭原则”。
如果说工厂模式的逻辑判断(具体返回那个实例)在内部,那么工厂方法模式就是把逻辑判断移动到了客户端,因为客户需要知道具体想创建的实例在那个工厂才可以创建。