工厂模式主要是为创建对象提供了接口(接口编程)。工厂模式依照《Java与模式》中的提法分为3类:
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
这3种模式从上到下逐渐抽象,并且更具1般性。还有1种分类法,就是将简单工厂模式看为工厂方法模式的1种特例,两个归为1类。下面是使用工厂模式的两种情况:
- 在编码时不能预感需要创建哪一种类的实例。
- 系统不应依赖于产品类实例如何被创建、组合和表达的细节
小胖爱吃面,很喜欢那种,他可以连续1周吃面,最爱他妈做的手擀面!现在在外面实习,为了省点钱也为了解馋,每天晚上都吃面,每次吃他都在想,每次吃面还要自己做,真麻烦,等我以后有钱了,每天下馆子!每天吃面!
小胖励志成为1个IT大牛,现在实习也是时刻在学习新的知识,有1天他想“我吃面需要自己做,想吃甚么面也要自己找素材再做,好麻烦啊!”边想边写了端代码,以下:
/*
* 泡面好吃,但不能每天吃哦(记得加个蛋)
*/
public class InstantNoodle {
public void DoInstantNoodle(){
System.out.println("做泡面...");
}
}
/*
* 最爱西北拉面,好贵的说
*/
public class HandPulledNoodle {
public void DoHandPulledNoodle(){
System.out.println("做拉面...");
}
}
/*
* 夏天吃凉面,多放醋,酸爽由不得你
*/
public class ColdNoodle {
public void DoColdNoodle(){
System.out.println("做凉拌面...");
}
}
public class EatNoodle {
public static void main(String[] args) {
//每天吃泡面
InstantNoodle instantNoodle = new InstantNoodle();
instantNoodle.DoInstantNoodle();
//想吃拉面了
HandPulledNoodle handPullNoodle = new HandPulledNoodle();
handPullNoodle.DoHandPulledNoodle();
}
}
这几段程序分别是泡面、拉面和凉面,最后1个吃面测试类,小胖看着程序运行的结果,心想,这样的代码看着总是有点别扭,我1个吃面的想吃各种各样的面,莫不成都要自己做啊,哪有时间学啊!代码虽然可以运行,但是之间的依赖性很高,后期不好保护啊!
小胖挠了挠脑袋,改了改代码,
/*
* 他大舅他2舅都是面条
*/
public interface Noodles {
public void DoNooles();
}
public class ColdNoodel implements Noodles {
@Override
public void DoNooles() {
System.out.println("做凉面");
}
}
public class HandPulledNoodle implements Noodles {
@Override
public void DoNooles() {
System.out.println("做拉面...");
}
}
public class InstantNoodle implements Noodles {
@Override
public void DoNooles() {
System.out.println("做泡面...");
}
}
/*
* 有请中华小当家中的面点王谢师傅
*/
public class MasterXie {
public Noodles doNoodles(String type){
if(type.equals("泡面")){
return new InstantNoodle();
}else if(type.equals("拉面")){
return new HandPulledNoodle();
}else{
return new ColdNoodel();
}
}
}
public class EatNoodle {
public static void main(String[] args) {
//谢师傅来了
MasterXie mx = new MasterXie();
//"小胖,要吃甚么?"
Noodles noodle = null;
//"谢师傅!我要吃泡面!!!"
noodle = mx.doNoodles("泡面");
//"好的"
noodle.DoNooles();
//"谢师傅,我想吃凉面!"
noodle = mx.doNoodles("凉面");
//"好的"
noodle.DoNooles();
}
}
写完,长舒1口气“我都把谢师傅请来了,这下甚么面都可以吃了,自己也不用做了,哈哈哈”
这里把充当产品的面条抽象了出来(接口),并实现这1接口,由充当工厂类的谢师傅负责生产这些产品,这样写法使代码的耦合度下降,测试类不需要知道代码里都有甚么东西,只需要1个像谢师傅这样的工厂类存在,需要甚么就传1个参数,就会得到!但是如果继续增加1个类的话,就要把工厂类打开在里面修改,对工厂类不符合开闭原则,倒是对面条(不需要修改面条的代码)符合,小胖思考了好久,继续改代码
/*
* 让谢师附会分身术(抽象出来)
*/
public interface MasterXie {
public Noodles DoNoodle();
}
/*
* 凉面谢师傅
*/
public class ColdNoodleXie implements MasterXie {
@Override
public Noodles DoNoodle() {
// TODO Auto-generated method stub
return new ColdNoodle();
}
}
顺次有泡面谢师傅和拉面谢师傅
public class EatNoodle {
public static void main(String[] args) {
//谢师傅"小胖,要吃甚么?","泡面"
//"我会分身术,专门分出1个做泡面的谢师傅给你"
MasterXie mx = new InstantNoodleXie();
Noodles noodle = mx.DoNoodle();
noodle.DoNooles();
}
}
这里把生产者和产品均抽象了出来,让生产者与被生产者逐一对应,更加便于保护
到这里,小胖想到,即使是吃1碗面,都要使用这么复杂的程序,那末以后就要更加努力的赚钱,自己只要撒钱就好了!!!
(希望各位看客给小胖留言,小胖会逐一接受并作出修改的!!!!)