【通俗易懂】一天一个设计模式----工厂模式

文章目录

前言
正文----什么是工厂模式?
----------小徐家的水果店🍇
----------工厂模式
----------工厂方法模式
----------抽象工厂方法模式

👉想看通俗易懂的单例模式戳这里


前言

对于初学者来说,工厂模式是晦涩难懂的,但是对于看到本文的初学者来说,工厂模式是生动形象的。本文旨在使用通俗易懂的例子,帮助初学者理解工厂模式。


什么是工厂模式?

下面是一段定义(很难理解,看不懂直接跳过就完事了😄)

工厂模式(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();
		
	}
 
}

其他物品类似




希望大家看完此文能够对工厂模式有一个比较清晰的认识,码字不易,尊重原创,转载请加入本文链接—查看原文

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值