Java 通过工厂模式和接口泛型实现完全解耦

首先我们假设:

  • 有一个农民(farmer)
  • 有一本菜谱(cookbook),为了方便理解菜谱只有炸鸡这一个菜

假设这是程序的两部分,分别可以被单独复用.并且农民被复用时有时需要菜谱上的函数做饭,有时忙不过来,就不按照菜谱做饭了,直接泡方便面.

如果不够详细的话可以这么理解:

农民是单身,所以为了回家不挨饿,他在浏览器里收藏了一个菜谱.也就是说,农民主要被用来干活,但不管是务农还是扛砖,为了不饿着每天都要带着手机看菜谱.但农民根据雇主的不同,不会每天都按照菜谱做饭,因为有时太忙了,就随便泡个方便面吃,然后继续干活.

而炸鸡的菜谱不止农民收藏了,镇子里的100个饭店也收藏了,饭店跟农民一毛钱关系都没有,饭店需要可以直接照着菜谱做饭.

所以:

  • 这个菜谱谁都可以用
  • 这个农民可以被任何老板雇佣
  • 有的老板雇佣农民时不许带手机,只能泡方便面,所以菜谱与农民不总在一起.

此时文件结构为:

  • 文件夹 farmer
    • 类Cook
    • 接口CookingMethod
    • 接口CookingMaterial
    • 类CookingFactory
  • cookbook
    • 类Chicken
    • 接口ChickenInterf
    • 类FryMethod
    • 接口FryInterf

farmer下有一个Cook类,这个类中有个方法要制作午餐.但此时不能直接调用Chicken与FryMethod.因为有可能不让带菜谱,只能吃泡面.

所以,不能在Cook类中出现Chicken与FryMethod.而要农民定义出对食材与方法的要求,也就是接口.无论中午吃什么食材(方便面还是鸡肉),都要满足农夫的要求CookingMaterial.无论是炸(鸡)还是泡(面),都要满足CookingMethod.至于选择炸鸡还是泡面,则由CookingFactory选择,选择完后,对应给农民的CookingMaterial和CookingMethod(就是方法的重载罢了).也就是说,如果farmer文件夹下出现Chicken与FryMethod,那么只可能是在CookingFactory类中.注意不可避免的是,每次这个农民被拿去用,这个类都要按需手动修改.

public class Cook {

    public void cook() {
        CookingMaterial material = new CookingFactory().getCookingMaterial();
        CookingMethod method = new CookingFactory().getCookingMethod();
    }

}
public class CookingFactory {

    public CookingMaterial getCookingMaterial() {
        return new Chicken();
    }

    public CookingMethod getCookingMethod() {
        return new FryMethod();
    }

}
public interface CookingMaterial {
    void printMaterialName();
}
public interface CookingMethod {
    void heatFood(CookingMaterial material);
}

这样就实现了farmer包每次被拿去用,只要改CookingFactory这一个文件就好.至于为什么不直接改Cook类,因为Cook类中可能有10000处地方使用了Chicken,不可能挨着改的,CookingFactory则只将Chicken与CookingMaterial对接.然后在Cook类中所有需要使用Chicken的地方全写CookingMaterial就好了.

至此农民可被独立使用的问题解决了.


但菜谱也要被独立使用,如果FryMethod继承了农民的CookingMethod那么饭店就不能用了.所以菜谱也定义出它自己的接口FryMethodInterf.然后FryMethod继承FryMethodInterf.可是别人拿去怎么用呢?好的,每个使用菜谱的人,不管是农民还是白领还是厨师,都要提供自己的要求给菜谱,然后菜谱的FryMethodInterf继承所有这些要求(接口是可以多继承的),这些要求不能被满足的话就在FryMethod里完善.

这样实现了菜谱的相对独立,缺点是这本菜谱非常厚,因为它详细的介绍了大厨应该怎么做炸鸡,白领应该怎么做炸鸡,农民应该怎么做炸鸡,有点像维基百科了,但也没关系,因为每个人用的时候只会用到关于自己的部分.也就是说菜谱单独使用时,只需要在FryMethodInterf里添加一些继承,然后把没有的方法在FryMethod中补上.

public interface ChickenInterf extends CookingMaterial {
    //这里留空即可,有用的这个接口都继承了,没用的写出来也没用-_-
}
public class Chicken implements ChickenInterf {

    @Override
    public void printMaterialName() {
        System.out.println("chicken");
    }

}
public interface FryMethodInterf extends CookingMethod {
}
public class FryMethod implements FryMethodInterf {
    @Override
    public void heatFood(CookingMaterial material) {
        //balabalala
    }
}

好像很完美,等等!!!FryMethod里为毛出现了农民的CookingMaterial作为参数????这个heat难道不是所有人做炸鸡都要用到的Chicken吗???

直接将CookingMaterial换成Chicken就不是覆写了,显然不行!!!那就泛型吧.

直接改成泛型也是不行的,要改动三个类四处地方:

  • CookingMethod改为
public interface CookingMethod<C extends CookingMaterial> {
    void heatFood(C material);
}
  • FryMethodInterf改为
public interface FryMethodInterf extends CookingMethod<Chicken> {
}
  • FryMethod改为
public class FryMethod implements FryMethodInterf {
    @Override
    public void heatFood(Chicken material) {
        //balabalala
    }
}

至此,cookbook下只有接口的继承中出现了farmer文件夹下的内容,别的程序用时删掉即可,同一程序不同模块用时只要多继承上这个模块的接口就好;farmer下只有CookingFactory中有cookbook的内容,如果需要可以很方便替换成paofangbianmian文件夹下的内容.基本上实现了没有第三方接口存在下的完全解耦.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值