欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-01-21 14:24:10
...

文章目录

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

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


前言

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


什么是工厂模式?

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

工厂模式(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反射学习