工厂方法模式:定义一个用于创建对象的接口,让子类去决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
工厂方法模式结构:
工厂类:
工厂总类:接口,定义抽象方法------创建运算类对象,不定义具体的执行细节,供工厂子类重写该方法
工厂子类:关联对应的运算子类,实现工厂总类这个接口,重写接口中定义的抽象方法------创建关联的运算子类对象,执行具体的创建过程
运算类:
运算总类:抽象类,定义抽象方法------运算,不定义具体的执行细节,供运算子类重写该方法
运算子类:继承运算总类这个抽象类,重写父类中定义的抽象方法,执行具体的运算细节
搞清楚工厂方法模式的结构之后,我们开看看代码怎么实现:
1、定义运算总类:这是一个抽象类:
package supermanager; import lombok.Getter; import lombok.Setter; /** * Created by Administrator on 2017/8/3. */ @Getter @Setter public abstract class Option { private String name1; private String name2; public abstract void getResult(); }
2、定义工厂总类,这是一个接口:
package superfactory; import supermanager.Option; /** * Created by Administrator on 2017/8/3. */ public interface SuperFactory { Option createOption(); }
3、定义多个运算子类:
package branchmanager; import supermanager.Option; /** * Created by Administrator on 2017/8/3. */ public class AudiOption extends Option{ @Override public void getResult() { System.out.println(super.getName1() + " : " + super.getName2() + ", 今天开什么车去上班啊"); System.out.println(super.getName2() + " : 今天心情好,开奥迪上班。"); } }
package branchmanager; import supermanager.Option; /** * Created by Administrator on 2017/8/3. */ public class BenzOption extends Option{ @Override public void getResult() { System.out.println(super.getName1() + " : " + super.getName2() + ", 今天准备怎么去上班啊"); System.out.println(super.getName2() + " : 今天啊,开奔驰。"); } }
package branchmanager; import supermanager.Option; /** * Created by Administrator on 2017/8/3. */ public class BmwOption extends Option{ @Override public void getResult() { System.out.println(super.getName1() + " : " + super.getName2() + ", 今天要开什么车去上班啊"); System.out.println(super.getName2() + ": 今天开宝马上班,其他车借出去了"); } }
package branchmanager; import supermanager.Option; /** * Created by Administrator on 2017/8/3. */ public class FerrariOption extends Option{ @Override public void getResult() { System.out.println(super.getName1() + " : " + super.getName2() + ", 今天开什么车去上班啊"); System.out.println(super.getName2() + ": 今天赶时间,开法拉利上班"); } }
4、定义与运算子类关联的多个工厂子类:
package branchfactory; import branchmanager.AudiOption; import superfactory.SuperFactory; import supermanager.Option; /** * Created by Administrator on 2017/8/3. */ public class AudiFactory implements SuperFactory { public Option createOption() { return new AudiOption(); } }
package branchfactory; import branchmanager.BenzOption; import superfactory.SuperFactory; import supermanager.Option; /** * Created by Administrator on 2017/8/3. */ public class BenzFactory implements SuperFactory { public Option createOption() { return new BenzOption(); } }
package branchfactory; import branchmanager.BmwOption; import superfactory.SuperFactory; import supermanager.Option; /** * Created by Administrator on 2017/8/3. */ public class BmwFactory implements SuperFactory { public Option createOption() { return new BmwOption(); } }
package branchfactory; import branchmanager.FerrariOption; import superfactory.SuperFactory; import supermanager.Option; /** * Created by Administrator on 2017/8/3. */ public class FerrariFactory implements SuperFactory { public Option createOption() { return new FerrariOption(); } }
import branchfactory.AudiFactory; import org.junit.Test; import superfactory.SuperFactory; import supermanager.Option; /** * Created by Administrator on 2017/8/3. */ public class TestFactoryMethod { @Test public void testOption(){ SuperFactory superFactory = new AudiFactory(); Option option = superFactory.createOption(); option.setName1("邻居老李"); option.setName2("张总"); option.getResult(); } }
测试效果如下所示:
说到工厂方法模式,就不得不提简单工厂模式了,我们先来看一下两者增加新功能的步骤。
简单工厂模式:(1)添加目标功能的功能类,(2)更改工厂方法,增加 switch...case 中的分支判断,过程中需要修改原有工厂类代码,破坏开闭原则,但是客户端该创建哪一个功能对象就不需要操心了,因为这一切都交给工厂类的逻辑代码判断完成。
工厂方法模式:(1)添加目标功能的功能类,(2)添加与目标功能类关联的工厂子类,并不需要对工厂类做修改,符合开闭原则,只是客户端需要知道,应该创建众多工厂子类中的哪一个,用它来完成创建运算子类对象的任务,也就是说,工厂方法把简单工厂的内部逻辑判断转移给客户端代码来执行,你想要的功能,本来是该工厂类的,现在变成修改客户端。
工厂方法模式总结:工厂方法模式克服了简单工厂违背开闭原则的缺点,并且保持了封装对象创建过程的优点,他们都是集中封装了对象的创建,是的要更换对象时,不需要做打的改动就能实现,降低了客户程序与产品对象的耦合,工厂方法模式是简单工厂模式的进一步抽象与推广。
好了,工厂方法模式的介绍基本到此结束。