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

什么是工厂方法

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

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

结构类图

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

举个栗子

漫威电影里每个英雄都有各自的能力/技能【+ 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();

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

需求改变

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

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

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

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

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

总结

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

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

参考文章
blog.csdn.net/hguisu/arti…
blog.csdn.net/zhengzhb/ar…

    原文作者:算法小白
    原文地址: https://juejin.im/entry/59279b310ce463006b0298a2
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞