案例分析工厂设计模式(简单-复杂-抽象)

浅谈工厂设计模式--本次试验将工厂模式分为三个层次(简单工厂模式、复杂工厂模式、抽象工厂模式),并各自讲解联系,由浅到深。

工厂模式出现的情况类似如下情况:

现有类ABCDD中有方法d

此后分别在ABC中实例化D对象并调用d()方法

此时考虑如下情况:如果出现功能类似D的类E,并打算用Ee()取代d()方法,那么我们就需要在ABC、中分别修改D对象和d()方法为E对象和e()方法,这将是是非常麻烦的事情,甚至有更多的类调用了Dd()方法。

假设场景:有一个Person(),他有一个吃鱼的方法eatFish(),那么在每次他吃鱼之前我们都要为他提供一条鱼。

(Fish)2种,分别为红鱼(RedFish)和黑鱼(DarkFish),每条鱼都有一个String name属性和getName()方法。

Person在吃鱼时,都会输出吃的鱼的名称。

思考:如果我们在PersoneatFish()中直接 RedFish redFish = new RedFish();,那么当我们打算将红鱼换成黑鱼的时候就会出现之前所讨论的情况。

现在我们先来看简单工厂设计模式

因为Person吃鱼主要是调用鱼的getName()得到鱼的name,所有我们将所有的鱼的getName()方法抽象为一个接口方法,将鱼抽象为一个接口类,而红鱼、黑鱼等鱼都实现了鱼(Fish)这个接口。

interface Fish{

String getName() ;

}

class RedFish implements Fish {

@Override

public String getName() {return "红鱼";}

}

class DarkFish implements Fish {

@Override

public String getName() {return "黑鱼";}

}

之后,我们来定义Person类:

class Person {

public void eatFish() {}

}

至此,我们要开始定义我们的工厂类了,我们打算通过工厂类来调用不通的鱼返回给Person对象,那么我们需要在Person中定义一个Fish对象的引用,用来接收工厂返回的鱼的对象,这里我们就用Fish fish这个引用来接收(因为所有的鱼都实现了Fish接口,相当是Fish的子类,所以这里是父类引用指向子类对象,这是java的多态性)。

此后,我们开始定义我们的Factory,并提供static Fish getFishName ()方法:

class FishFactory{

public static Fish getFishName() {return null; }

}

到这里,最基本的对象我们已经分析、定义完毕,接下来我们开始来组合它们:

因为人要吃鱼,首先要获得鱼这个对象,所以我们要先通过FishFactory返回我们的鱼,修改如下:

class FishFactory{

public static Fish getFishName() {

Fish fish = new DarkFish();

return fish;

}

}

class Person {

private Fish fish = null;

public void eatFish() {

fish = FishFactory.getFishName();

System.out.println("我吃的是"+fish.getName());

}

}

如此修改后,当人吃鱼的时候就可以通过修改FishFactory中的Fish对象来控制人吃的鱼的种类,也就避免了在人吃鱼的时候多出修改不同鱼的对象。

至此,人吃鱼这个简单工厂设计模式讲述完毕。

总结:上述简单工厂模式降低了类之间的耦合度,但任然存在不足的地方,因为当我们要更换不同的鱼的种类的时候,我们都要在工厂类中修改,而且每次只能提供一种鱼,这是非常不现实的。

图示:

现在我们来看复杂工厂设计模式

在简单工厂模式的基础上,我们发现:每次吃鱼都只能返回一种,如果是我同的Person想要吃不同的鱼,那么就没法满足了,所以我们在简单工厂设计模式的基础上做出修改:

我们分别为不同的鱼提供不同的工厂类,但是这些工厂类都必须实现相同的接口类,且这个工厂接口类,必须提供一个返回生产具体鱼的工厂类。

方案:

FishFactory抽象为一个接口,包含方法:productFish ()放回具体鱼对象

定义两个工厂类(RedFishFactoryDarkFishFactory),并实现接口FishFactory

interface FishFactory{

public Fish productFish() ;

}

class DarkFishFactory implements FishFactory{

@Override

public Fish productFish() {

return new DarkFish();

}

}

class RedFishFactory implements FishFactory{

@Override

public Fish productFish() {

return new RedFish();

}

}

此时,在对人吃鱼进行下述修改:

class Person {

private FishFactory fishFactory = null;

public void eatFish() {

fishFactory = new DarkFishFactory();//也可以使RedFishFactory

System.out.println("我吃的是"+fishFactory.productFish().getName());

}

}

可能有读者认为在人吃鱼的时候每个地方都要fishFactory = new DarkFishFactory();,不是和我们最上面讨论的一样,如果工厂改了不就要到处改了吗?那么我想说的是:我们每次生产的对象是鱼,所以我们最多也就是在不同的工厂上更换上不同的鱼,而不是去更换对应的工厂。

虽然如此,但是这还是显现了对象和程序的耦合性,所以,我们将在下面进一步的降低他们的耦合度。

最后是抽象工厂设计模式:我们也是基于复杂工厂设计模式,其实只要稍稍改下也就差不多了。

方案:

我们添加一个返回工厂的类ProductFactory,并提供一个静态方法:getFactoryInstance(),代码如下:

class ProductFactory{

public static FishFactory getFactoryInstance(String factoryType) {

if(factoryType.equals("黑鱼")) {

return new DarkFishFactory();

}else if(factoryType.equals("红鱼")) {

return new RedFishFactory();

}

return null;

}

}

此外,修改人吃鱼的方法:

class Person {

private FishFactory fishFactory = null;

public void eatFish() {

fishFactory = ProductFactory.getFactoryInstance("红鱼");

System.out.println("我吃的是"+fishFactory.productFish().getName());

}

}

综上,我们已经完成了抽象工厂模式的设计,当我们需要修改返回的鱼的类型的时候,我们只要修改对应的String factoryType参数就行了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WJL_MGQS

本不富裕的收入,还得买服务器

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值