Java设计模式——工厂方法(Factory Method)

来源:互联网 发布:微积分中d含义,知乎 编辑:程序博客网 时间:2024/05/12 07:42

什么是工厂方法

定义一个创建产品对象的工厂接口,让子类决定实例化哪一个类,将实际创建工作推迟到子类当中。它的核心结构有四个角色,分别是

  1. 【抽象工厂】Factory : 具体工厂类必须实现这个接口。在实际的系统中,这个角色也常常使用抽象类实现。
  2. 【具体工厂】ConcreteFactory : 实现了抽象工厂接口的具体类。具体工厂角色含有与业务密切相关的逻辑。
  3. 【抽象产品】Product : 定义具体产品类所需要实现的逻辑和功能方法。
  4. 【具体产品】 ConcreteProduct : 实现具体逻辑和功能的类。

结构类图

这里写图片描述

举个栗子

漫威电影里每个英雄都有各自的能力/技能【+ skill()】,下面我们简单的用【智力】,【力量】,【格斗技巧】来分配对应的英雄,这样就可以对抗不同实力的敌人。


工厂及具体实现工厂【HeroFactrory】
public interface iHeroFactory {//定义具体工厂类所需要实现的逻辑和功能方法。    iHero callTheHero();}
class StrengthFactory implements iHeroFactory {//力量型英雄选择工厂    @Override    public iHero callTheHero() {        return new Hulk();    }}
public class FightFactory implements iHeroFactory {//格斗型英雄选择工厂    @Override    public iHero callTheHero() {        return new Hawkeye();    }}
public class IqFactory implements iHeroFactory {//智力型英雄选择工厂    @Override    public iHero callTheHero() {        return new USACaptain();    }}

产品及具体实现的产品【Hero】
interface iHero {//定义具体产品类所需要实现的逻辑和功能方法。    void skill();//定义旗下产品都有的技能方法}
class Hulk implements iHero {    @Override    public void skill() {        System.out.println("【绿巨人】【智力:5】【力量:7】【格斗技巧:5】");    }}
class Hawkeye implements iHero {    @Override    public void skill() {        System.out.println("【鹰眼】【智力:5】【力量:3】【格斗技巧:7】");    }}
class USACaptain implements iHero {    @Override    public void skill() {        System.out.println("【美国队长】【智力:6】【力量:3】【格斗技巧:6】");    }}

英雄分配和调度【客户程序】
        iHeroFactory factory1=new FightFactory();//来一个会格斗的        iHero hero1=factory1.callTheHero();        hero1.skill();        System.out.println("\n------------------------------------\n");        iHeroFactory factory2=new StrengthFactory();//来一个力气大的        iHero hero2=factory2.callTheHero();        hero2.skill();        System.out.println("\n------------------------------------\n");        iHeroFactory factory3=new IqFactory();//来一个聪明的        iHero hero3=factory3.callTheHero();        hero3.skill();

这里写图片描述


需求改变

使用工厂方法后,调用端的耦合度大大降低了。例如上面这个栗子,比如说新出现了一个需求

美国队长叛变!广电总局说了,把美国队长封杀,全部换成钢铁侠来完成任务。

现实中应该也会遇到这种需求,例如把所有的图片加载(例如之前使用imageLoader),全部改成Glide。如果你之前通过工厂方法来封装的图片加载,那么改一句代码即可。

public class IqFactory implements iHeroFactory {//智力型英雄选择工厂    @Override    public iHero callTheHero() {//        return new USACaptain();        return new IronMan();//我们只需要在工厂里替换【英雄】(产品)即可    }}

这里写图片描述

总结

工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口。那我们是否一定要在代码中遍布工厂呢?大可不必。也许在下面情况下你可以考虑使用工厂方法模式:

  • 当客户程序不需要知道要使用对象的创建过程。
  • 客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象。

参考文章
http://blog.csdn.net/hguisu/article/details/7505909
http://blog.csdn.net/zhengzhb/article/details/7348707

阅读全文
0 0