前言:在上一篇文章当中, 我们对简单工厂模式进行了分析, 他的缺点就是当我们有新的产品类需要生产的时候, 我们将会改变工厂类中的业务逻辑, 那样会违反开闭原则, 具体详细分析请见简单工厂模式。
如果用简单工厂模式, 去生产一系列的产品, 那么工厂类的业务逻辑将会更加繁重,产品类和工厂类之间的耦合度(可理解为工厂类与产品类之间的依赖程度)增加,将会严重的影响后期维护, 所以我们在这里又引入了一个新的设计模式, 它在简单设计模式的基础之上进行了改进, 我们称之为工厂方法模式(动态方法模式)
一、工厂方法模式
1、我的理解:
为了减轻一个厂生产多类产品的压力, 那么我们就需要多个厂来生产多产品, 产品和厂之间的关系为一一对应关系,
2、定义:
一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
3、例如:
在生活中的抽象模型:
我的定义:我们通过抽象类产品定义对应的产品, 然后将产品x送入与之唯一对应的工厂x进行生产。
建立方案:
1、首先我们需要建立一个产品基类(或者是接口)
2、我们还需要建立一个工厂基类(或者接口)。
3、在衍生出产品X的同时, 我们也要衍生出对应的工厂X对其进行生产。
二、试验模型:
试验内容:我们通过传入对用的产品类标志调用对应的工厂类进行生产产品
产品父类: 定义了Animal类接口
产品子类:继承父类并实现接口函数
工厂父类:定义了AnimalFactory工厂类接口
工厂子类:集成父类并且实现接口函数
uml类图如下:
代码如下:
Animal.java
package FactoryMethodPattern;
public interface Animal{
public void run();
}
Monkey.java
package FactoryMethodPattern;
public class Monkey implements Animal {
public void run(){
System.out.println("猴子飞瓜了");
}
}
Tiger.java
package FactoryMethodPattern;
public class Tiger implements Animal{
public void run(){
System.out.println("老虎跑瓜了");
}
}
AinamlFactory.java
package FactoryMethodPattern;
public interface AnimalFactory {
public Animal productAnimal(String str);
}
MonkeyFactory
package FactoryMethodPattern;
public class MonkeyFactory implements AnimalFactory {
public Animal productAnimal(String str){
if(str.equalsIgnoreCase("猴子")){
return new Monkey();
}else{
System.out.println(str+"创造失败");
return null;
}
}
}
TigerFactory
package FactoryMethodPattern;
public class TigerFactory implements AnimalFactory{
public Animal productAnimal(String str){
if(str.equalsIgnoreCase("老虎")){
return new Tiger();
}else{
System.out.println(str+"创造失败");
return null;
}
}
}
客户端程序:
package FactoryMethodPattern;
public class Factor {
public static void main(String[] args){
AnimalFactory af = new TigerFactory();
Animal tiger = af.productAnimal("老虎");
tiger.run();
AnimalFactory afaf = new MonkeyFactory();
Animal monkey = afaf.productAnimal("猴子");
monkey.run();
AnimalFactory afafaf = new TigerFactory();
afafaf.productAnimal("狗子");
}
}
老虎跑瓜了
猴子飞瓜了
狗子创造失败
三、总结
优先:
1、在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”
2、在工厂方法中,用户只需要知道所要产品的具体工厂,无须关系具体的创建过程,甚至不需要具体产品类的类名
缺点:
1、随着产品类的增多, 工厂类也会随之增多那么将会增加系统的复杂度,。
2、考虑到系统的可拓展性, 增加了系统的抽象性和理解难度, 到时候我们将引入了DOM、反射等技术。
备注:本程序没有引用java DAO层和反射技术, 因为本人是C++ 程序猿, 仅用java学习设计模式而已, 若有错误望各位指正