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

什么是工厂方法

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

  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

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值