【通俗易懂】一天一个设计模式----工厂模式
文章目录
前言
正文----什么是工厂模式?
----------小徐家的水果店????
----------工厂模式
----------工厂方法模式
----------抽象工厂方法模式
前言
对于初学者来说,工厂模式是晦涩难懂的,但是对于看到本文的初学者来说,工厂模式是生动形象的。本文旨在使用通俗易懂的例子,帮助初学者理解工厂模式。
什么是工厂模式?
下面是一段定义(很难理解,看不懂直接跳过就完事了????)
工厂模式(Factory Pattern)是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
小徐家的水果店
小徐家世代经商,以卖水果(????,????,????,????)为生。
小徐一开始只卖西瓜????这一种水果。
-
Day1
营业第一天,客户都赶来买西瓜????,有要1个的,有要666个的,小徐忙得不亦乐乎。Day2
第二天,生意依旧兴隆,小徐家新进了苹果????和桃子????,开始有点忙不过来了。有时候刚递过去一个桃子,那边又要三个西瓜,很是麻烦。
Day3
第三天,小徐从朋友那里得知,现在的水果自动贩卖机火的是一塌糊涂,于是斥巨资购买了一台,顾客只需要扫码支付,就能买到对应的水果了,小徐也是,只要事先把水果放到自动贩卖机里就完事了。
接下来就是事业的大丰收了,财源滚滚。很快小徐就购买了很多台贩卖机。
-
Day28
随着时间推移,贩卖机越来越多,小徐遇到了大麻烦,贩卖机太多了,现在新进的香蕉????,需要一个个添加到每一个贩卖机,不卖的苹果,需要一个个从每一个贩卖机删除,很是焦虑。
小徐索性直接建了一个大型水果工厂,里面放置了各种类型的独立水果贩卖机,有苹果贩卖机????,香蕉贩卖机????等等,这样下次新进一个水果种类的时候,直接添加一个新的贩卖机就行了,不需要改动其他的贩卖机。
-
Day100
100天后,水果厂的生意是越来越好,也解决了新进水果和撤走水果的频繁修改问题,小徐还想卖服装,这样一个水果工厂是不够了,干脆再建造一个服装工厂,然后同属于小徐公司(抽象工厂),公司内部为各大工厂提供了通道,顾客进入公司内部选择不同的通道就可以享受不同的工厂服务。
工厂模式
我们从水果店创业的故事来理解工厂模式。 下面是前面你看不懂的定义:工厂模式(Factory Pattern)是最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
翻译:小徐创业的模式是最常见的创业模式之一,这种类型的创业模式属于贩卖型模式,他提供了卖东西的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
翻译:在小徐创业的模式中,我们卖东西时不会对客户暴露我们是怎么制作的,并且是通过使用一个共同的通道来指向新创建的水果/服装工厂。
下面是干货:对于day1的情形,在我们写程序的过程中很常见:
public class SaleFruit{ //卖水果啦
public Apple I_Wang_A_Apple() { //我想要一个苹果
return new Apple();
}
public Banana I_Wang_A_Banana() { //我想要一个香蕉
return new Banana();
}
}
第二天,又新进了西瓜,客户想要西瓜,我就得做改动,加上一行
public class SaleFruit{ //卖水果啦
public Apple I_Wang_A_Apple() { //我想要一个苹果
return new Apple();
}
public Banana I_Wang_A_Banana() { //我想要一个香蕉
return new Banana();
}
public Watermolen I_Wang_A_Watermolen() { //我想要一个西瓜
return new Watermolen();
}
}
试问,这还是一个水果摊,如果小徐有多个水果摊位,有的摊位的固定客户就不喜欢西瓜,那么我还要针对该摊位的方法做出改动,把卖西瓜方法删掉,或者对于某个摊位我只保留卖苹果的方法,每个摊位都有不同的需求,都得处理,小徐的烦恼也就不奇怪了
接下来小徐采用的水果贩卖机(Day3的情形),就是我们的工厂模式,通过顾客指定想要的水果(参数),来售卖指定的水果,返回指定对象,这样就能应对所有的奇葩水果要求(想要什么水果自己拿,不想要的水果其他顾客也会要,不会像摊位一样万一用户不要某一种水果,水果就浪费了—(浪费内存空间),增加卖水果人员的负担(可维护性难度加大))。
比如下面的代码
public interface Fruit{
public void sale();//卖出水果
}
public class SaleFruit{ //卖水果啦
public Fruit I_Wang_A_Fruit_It_Name_is_argument(String name) {
//我想要一个水果,他的名字在参数中
if(name.equals("apple")){
return new Apple();
}else if(name.equals("banana")){
return new Banana();
}else if(name.equals("watermolen"))
return new Watermolen();
else{
return null;
}
}
}
这样就相当于统一了起来,不用像刚开始对每一个摊位做特殊处理(每一个文件里面写一些创建对象的方法,而是直接通过统一的方法(水果贩卖机)传参来获取不同的对象)
有人可能说为什么不直接按照不同水果类型创建不同的摊位,恭喜你,你的思维已经跳跃到了水果工厂的层面,他与水果工厂里面有不同的贩卖机想法一致,但我们为了更形象的说明工厂模式各种情形下的转变,还是不得不提一下这种混合类型的“水果贩卖机”
现在这样看起来还不错,没有了那么多可维护的文件,不同对象都是直接通过参数的不同来获取,也确实,小徐在这种工厂模式下赚了不少钱,但是细细想来,这种方式他真的没有缺点吗?
不是,他并不遵循
开闭原则!!!!!
开----扩展开放,可以修改行为,但是不允许改变他的源代码
闭----修改封闭,可以修改行为,但是不允许改变他的源代码
下面的代码,如果新进了水果种类,势必要增加一个else-if语句,相当于修改了源代码
public class SaleFruit{ //卖水果啦
public Fruit I_Wang_A_Fruit_It_Name_is_argument(String name) {
//我想要一个水果,他的名字在参数中
if(name.equals("apple")){
return new Apple();
}else if(name.equals("banana")){
return new Banana();
}else if(name.equals("watermolen"))
return new Watermolen();
else{
return null;
}
}
}
工厂方法模式
我们把每一个水果种类分类,分成不同的水果贩卖机,散落在水果工厂里。(对应于Day28的情形) 首先是我们的水果工厂,一个接口。public interface FruitFactory {
public Shape getFruit();
}
好多水果种类:
//苹果
public class AppleFactory implements FruitFactory {
@Override
public Fruit getFruit() {
return new Apple();
}
}
//香蕉
public class BananaFactory implements FruitFactory {
@Override
public Fruit getFruit() {
return new Banana();
}
}
如果需要进其他水果,我们只需要添加一个类就可以了,不用改动源代码的if语句,同理,如果撤走一个水果种类,直接删除该类就可以了,不用改动源代码。
具体创建水果可以采用下面的代码:
public class SaleFruit{
public static void main(String[] args) {
FruitFactory appleFactory = new AppleFactory ();
appleFactory.getFruit().sale();
FruitFactory bananaFactory = new BananaFactory ();
bananaFactory.getFruit().sale();
}
}
抽象工厂方法模式
时光流转,水果工厂开了100天了,我们的项目也越做越大,恐怕是现有的规模已经不满足我们的需求,所以我们干脆再抽象出一层(成立小徐公司),为之前的每一个接口(每一个工厂提供通道)提供创建对象的方法,从而继续达到开闭原则的目的。注意这个时候是否使用抽象工厂模式跟项目的具体规模有关,有时候规模从大降低到小的时候可能使用工厂方法模式更合适一些,具体情况具体分析
public interface LittleXuCompany {//小徐公司
public FruitFactory createButtonFruitFactory();//水果工厂
public ClothFactory createClothFactory();//服装工厂
}
我们卖苹果可以这样
public class AbstractFactoryDemo {
public static void main(String[] args) {
LittleXuCompany fruitFactory = new FruitFactory ();
fruitFactory.createButtonFruitFactory().getFruit().sale();
}
}
其他物品类似
希望大家看完此文能够对工厂模式有一个比较清晰的认识,码字不易,尊重原创,转载请加入本文链接—查看原文。
上一篇: strcpy()/memcpy()
下一篇: Java反射学习