【一个故事】
话说三国时期,西凉刺史董卓乘朝野之战,统领二十万大军进驻洛阳,废了少帝,立了献帝,自封为相国(还挺好意思)。董卓为人残暴,欺主弄权,朝中正直大臣都想杀之而后快,然而,董卓权倾朝野,位高权重,身边还有号称天下第一勇武吕布陪伴左右(吕布这不是助纣为虐吗),无人敢近,众大臣只能恨于心中。校尉曹操(主角出场),足智多谋,早有杀董之心。一日,在大司徒王允处借的七星宝刀,进府行刺董卓。
曹操得了七星宝刀,喜出望外,心想,这下我可有出头之日了,只要杀了董贼,我就是英群,名垂千古,万世流芳!(暗笑)哈哈……于是身藏宝刀,来到相府,等待刺杀时机。
董卓见到曹操,问:“孟德为何来得这么晚?”曹操说:“我的马儿比较瘦,跑不快。”董卓说:“没事,我有的是好马,让吕布去给你挑一匹。”于是自己就躺在榻上休息了,吕布也出去了,曹操一看,机会来了,急抽刀欲刺之,但是宝刀光芒四射,被铜镜反射到了董卓的脸上,董卓猛然起身,问:“你要干嘛?”恰巧,挑马的吕布回来了,机智的曹操说:“偶得宝刀一把,欲献给丞相。”董卓顺手接过宝刀:“不错,好刀!”曹操又说:“我想试试马,希望丞相能恩准。”于是曹操借马飞驰而去。过了一会儿,董卓一拍大腿说:“上当了!!!”(反射弧真长),但是曹操早已不见了踪迹。
【模式定义】
工厂方法模式(Factory Method Pattern),就是定义一个创建产品对象得工厂接口,让子类决定实例化哪一种实例对象,也就是将实际创建实例对象得工作推迟到子类当中,核心工厂类不再负责具体产品得创建。
工厂方法模式是对简单工厂模式进行了抽象。
【静态建模】
大司徒王允——抽象工厂(负责提供宝刀)ISwordFactory
各类宝刀——抽象产品(各类宝刀)AbstractSword
校尉曹操——具体工厂(获得七星宝刀)Caocao
七星宝刀——具体产品(宝刀中的一类)QixingSword
【代码实现】
工程结构图:
1、抽象宝刀——AbstractSword
package com.demo.factory.model;
/**
* 定义抽象宝刀
* Created by 丽杰 on 2017/6/3.
*/
public abstract class AbstractSword {
//宝刀的名称
private String name;
//抽象宝刀的构造方法
public AbstractSword(){
}
//获得宝刀名称
public String getName() {
return name;
}
//设置宝刀名称
public void setName(String name) {
this.name = name;
}
}
2、具体宝刀(七星宝刀)——QixingSword
package com.demo.factory.model.object;
import com.demo.factory.model.AbstractSword;
/**
* 七星宝刀类
* Created by 丽杰 on 2017/6/3.
*/
public class QixingSword extends AbstractSword{
/**
* 构造方法设置宝刀的名称
*/
public QixingSword(){
this.setName("七星宝刀");
}
}
3、抽象宝刀工厂——ISwordFactory
package com.demo.factory.itf;
import com.demo.factory.model.AbstractSword;
/**
* 宝刀工厂
* Created by 丽杰 on 2017/6/3.
*/
public interface ISwordFactory {
/**
* 生产各类宝刀(返回值是抽象宝刀类型)
*/
public AbstractSword createSword();
}
package com.demo.factory;
import com.demo.factory.itf.ISwordFactory;
import com.demo.factory.model.AbstractSword;
import com.demo.factory.model.object.QixingSword;
/**
* 曹操具体工厂
* Created by 丽杰 on 2017/6/3.
*/
public class Caocao implements ISwordFactory {
/**
* 实现ISwordFactory接口的createSword方法,生产七星宝刀
*/
public AbstractSword createSword(){
return new QixingSword();
}
}
5、主应用程序——MainApp
package com.demo;
import com.demo.factory.Caocao;
import com.demo.factory.Caocao2;
import com.demo.factory.model.AbstractSword;
import com.demo.factory.itf.ISwordFactory;
/**
* Created by 丽杰 on 2017/6/3.
*/
public class MainApp {
public static void main(String[] args){
//创建曹操实例对象(返回使用接口类型ISwordFactory)
ISwordFactory swordFactory = new Caocao();
//获得宝刀实例——七星宝刀c
AbstractSword sword = swordFactory.createSword();
//刺杀董卓
System.out.print("曹操使用"+sword.getName()+"刺杀董卓!");
}
}
【八星宝刀】
刺杀一次失败后,曹操痛定思痛,决定“二进宫”,感觉八星宝刀比七星宝刀多一星,应该能增加刺杀的胜算,于是向王允借八星宝刀。(杜撰)
1、八星宝刀——BaxingSword
package com.demo.factory.model.object;
import com.demo.factory.model.AbstractSword;
/**
* Created by 丽杰 on 2017/6/3.
*/
public class BaxingSword extends AbstractSword{
/**
* 构造方法设置宝刀的名称
*/
public BaxingSword(){
this.setName("八星宝刀");
}
}
2、具体宝刀工厂(生产八星宝刀)——Caocao2
package com.demo.factory;
import com.demo.factory.itf.ISwordFactory;
import com.demo.factory.model.AbstractSword;
import com.demo.factory.model.object.BaxingSword;
/**
* Created by 丽杰 on 2017/6/3.
*/
public class Caocao2 implements ISwordFactory{
//生产八星宝刀
public AbstractSword createSword(){
return new BaxingSword();
}
}
3、 主应用程序——MainApp
package com.demo;
import com.demo.factory.Caocao;
import com.demo.factory.Caocao2;
import com.demo.factory.model.AbstractSword;
import com.demo.factory.itf.ISwordFactory;
/**
* Created by 丽杰 on 2017/6/3.
*/
public class MainApp {
public static void main(String[] args){
//创建曹操实例对象(返回使用接口类型ISwordFactory)
// ISwordFactory swordFactory = new Caocao();
ISwordFactory swordFactory = new Caocao2();
//获得宝刀实例——八星宝刀c
AbstractSword sword = swordFactory.createSword();
//刺杀董卓
System.out.print("曹操使用"+sword.getName()+"刺杀董卓!");
}
}
4、运行效果
【小结】
1、工厂方法模式
定义一个创建产品对象的工厂接口,让子类决定实例化哪一种实例对象,也就是将实际创建实例对象的工作推迟到子类当中,核心工厂类不再负责具体产品的创建。
2、设计模式
(1)“开-闭”原则:对扩展开放,对修改关闭。
(2)依赖倒置原则:不论工厂还是产品都应该依赖于抽象,而不是具体的实现类。
3、工厂方法模式的使用场合
(1)当子类型可能会有很多,以后需要不断增添不同的子类实现时;
(2)当一个系统尚在框架设计阶段,还不知道将来需要实例化实例化哪些具体类时;
(3)系统设计之初不需要具体对象的概念(或者说没有具体对象的概念)。