工厂方法的定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。
工厂方法使一个类的实例化延迟到其子类。
在以后的分析中,我使用的例子是学习设计模式之禅上面的例子。这也算是我对这本书学习的一个总结。如果需要下载这本书,请点击设计模式之禅。
优点:
1、良好的封装性,代码结构清晰。
2、扩展性也是工厂方法的一个优点。
3、屏蔽产品类。使调用者只关心产品的接口,不用关注实现的变化。
4、降低了模块之间的耦合性。
工厂方法的类图:
实现代码:
工厂抽象类
package com.designpatterns.factorymethod; public abstract class AbstractHumanFactory { public abstract <T extends Human> T createHuman(Class<T> c); }工厂实现类;
package com.designpatterns.factorymethod; public class HumanFactiry extends AbstractHumanFactory { @Override public <T extends Human> T createHuman(Class<T> c) { Human human = null; try { human = (Human) Class.forName(c.getName()).newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { System.out.println("造人失败!"); } return (T) human; } }
package com.designpatterns.factorymethod; public interface Human { public void getColor(); public void talk(); }
黑人类:
package com.designpatterns.factorymethod; public class BlackHuman implements Human { @Override public void getColor() { System.out.println("我黑色皮肤!"); } @Override public void talk() { System.out.println("我说话你听不懂!"); } }
package com.designpatterns.factorymethod; public class WhiteHuman implements Human { @Override public void getColor() { System.out.println("我是白色皮肤!"); } @Override public void talk() { System.out.println("我说话,是一个字节!"); } }
黄种人类:
package com.designpatterns.factorymethod; public class YellowHuman implements Human { @Override public void getColor() { System.out.println("我是黄色皮肤!"); } @Override public void talk() { System.out.println("我说话,是两个字节!"); } }
package com.designpatterns.factorymethod; public class NvWa { public static void main(String[] args) { AbstractHumanFactory YYL = new HumanFactiry(); System.out.println("----------------White People---------------"); Human whiteHuman = YYL.createHuman(WhiteHuman.class); whiteHuman.getColor(); whiteHuman.talk(); System.out.println("----------------Black People---------------"); Human blackHuman = YYL.createHuman(BlackHuman.class); blackHuman.getColor(); blackHuman.talk(); System.out.println("----------------Yellow People---------------"); Human YellowHuman = YYL.createHuman(YellowHuman.class); YellowHuman.getColor(); YellowHuman.talk(); } }
一、简单工厂:一个模块仅需要一个工厂类,没有必要把它生产出来,使用静态的方法就可以了。
我们将工厂的抽象类去掉,然后修改实现类的方法为静态方法即可。
类图如下:
二、多个工厂类:如果是一个复杂的项目的时候,所有的产品类都放到一个工厂方法中进行初始化会使代码结构不清晰。考虑到结构清晰,我们为每个产品定义一个创造者,然后由调用者自己去选择与哪个工厂方法关联。
类图如下:
抽象工厂:为创建一组相关或者相互依赖的对象提供一个接口,而且无需指定它们的具体类。
优点:
1、封装性。
2、产品族内的约束为非公开状态。缺点:
产品族扩展非常困难,违反开闭原则。(添加产品困难,支持添加产品族)
类图如下:
关于后面这三个模式的代码,我已经上传了。需要的同学可以自己去下载设计模式之工厂方法、简单工厂、抽象工厂的文档。
总结:
1、简单工厂算是工厂方法模式的弱化,因为简单所以叫做简单工厂模式。
简单工厂的工厂类扩展比较困难,不符合开闭原则,添加新的产品需要修改原来的代码。
2、工厂方法模式。
对同一类型的产品可以任意扩展。
3.抽象工厂模式是工厂方法模式的升级版。
在有多个业务类别或者分类的时候,可以用这种方法解决问题。
抽象工厂模式对在原有的产品族中添加一个新产品的扩展,会破坏开闭原则。但是对于添加一个新的产品族,则支持任意扩展。
最后,简单的来说:
简单工厂:对添加新产品无能为力。
工厂方法模式:支持添加同一类型任意的产品。
抽象工厂模式:对添加新产品无能为力,但支持添加新的产品族。