2、工厂模式

JAVA中的工厂模式也是一个重要的知识点,它除了在面试中问的比较多以外,这种模式的思想也是值得我们去学习的。

看了很多博客,大致的说法就是三类 简单工厂、工厂方法、抽象工厂,下面我们一一进行介绍,最后,我们再分析三种模式的区别。

图例参考

一 、简单工厂模式

业务场景: 简单工厂模式主要运用在业务比较简单的情况下,适用于那种很少扩展的情况,工厂类几乎不变。

角色组成

  1. 工厂类角色
  2. 抽象产品角色
  3. 具体产品角色
    图示参考:在这里插入图片描述
//抽象类,提取对象共有属性
abstract class Cup{
	
	private String name;
	private String price;
	public abstract void drink();	
}

//水杯
class WaterCup extends Cup{

	public void drink() {
		System.out.println("我喝水");	
	}	
}

//咖啡杯

class CoffeeCup extends Cup{

	public void drink() {
		System.out.println("我喝咖啡");	
	}
}

//简单工厂
public class SimpleFactory {
	public static Cup BuyCup(String str) {
		Cup cup = null;
		if(str.equals("买水杯")) {
			cup = new WaterCup();
		}else if(str.equals("买咖啡杯")) {
			cup = new CoffeeCup();
		}
		return cup;
	}
}

经过分析,客户端只负责消费产品,而不用自己去 “new"一个出来。从开闭原则方面来说,如果要增加一个新的产品,只需要再次继承抽象类即可,具有很好的扩展性(对扩展开放,对修改关闭)。但是在具体的工厂类中,需要判断多种业务,比较复杂。

二、工厂方法模式

角色组成:

  1. 抽象工厂角色
  2. 具体工厂角色
  3. 抽象产品角色
  4. 具体产品角色
    在这里插入图片描述
    下面 还是通过代码的方式来分析这几种角色,以及他相对简单工厂的优势。
//抽象工厂
abstract class Factory{
	public abstract Cup buyCup();
}

//水杯工厂
class WaterCupFactory extends Factory{
	public Cup buyCup() {
		return new WaterCup();
	}
}
//咖啡杯工厂
class CoffeeCupFactory extends Factory{
	public Cup buyCup() {
		return new CoffeeCup();
	}
	
}

这里将工厂进一步抽象,实现工厂方法模式。上面在介绍简单工厂时说,在一个工厂类里面需要有复杂的逻辑,但是在将工厂抽象后,一个工厂只负责生产一种商品,用户不需要知道创建细节,将业务逻辑隔离开,符合高内聚低耦合的原则。而且如果要是增加一种产品的话,只需要增加抽象工厂和抽象产品的子类,不需要修改原有的逻辑代码,扩展性较简单工厂更好,符合开闭原则。

三、抽象工厂模式

  抽象工厂模式可以说是对工厂方法模式进一步抽象,在介绍抽象工厂方法模式之前,先介绍一下产品族的概念。产品族,指的是由同一个工厂生产的,位于不同产品等级结构中的一组产品。举个例子说明一下,大家都知道在汽车产业中有两种车,他们分别是普通商务车、和超级跑车,而生产汽车的企业又有很多种,比如奥迪、奔驰等,奥迪生产的普通商务车和奔驰生产的普通商务车是同属于一个“普通商务车”这样一个产品族中。类似的,奥迪和奔驰生产的超级跑车又属于“超级跑车”这个产品族中。
上一节我们在介绍简单工厂的时候,设计思路是一个工厂生产某一个具体的产品,但是如果产品过多的话,就得建造n多个工厂,而抽象工厂则是从产品族层面近一步抽象,设计为一个工厂生产一个产品族的产品。例如,商务车工厂生产奥迪、奔驰等等牌子的普通商务车,超级跑车工厂生产奥迪、奔驰、bmw等等牌子的超级跑车。这就是抽象工厂模式。
在这里插入图片描述
上面图中,一行也就是一个颜色等级的图案就代表一个产品族,由一个工厂生产,这样本来由15个工厂才能满足的逻辑,使用抽象方法后,只需要5个工厂就能满足,下面还是用代码的方式来说明(这回分为普通水杯子和饮料杯子)

//分析的时候  把玻璃杯和塑料杯当成两个不同的产品  然后根据他们的特征
//   都能装水  和饮料  所以  把水和饮料当成两个产品族   建造两个工厂  每个工厂都能生产玻璃杯和塑料杯
//抽象类,塑料杯子抽象
abstract class PlasticCup{
	
	private String name;
	private String price;
	public abstract void drink();	
}

//抽象类,玻璃杯子抽象
abstract class GlassCup{
	
	private String name;
	private String price;
	public abstract void drink();	
}

//玻璃水杯
class WaterGlassCup extends GlassCup{

	public void drink() {
		System.out.println("我用玻璃杯喝水");	
	}	
}

//玻璃饮料杯
class DrinksGlassCup extends GlassCup{
	public void drink() {
		System.out.println("我用玻璃杯喝饮料");
	}
}

//塑料水杯
class WaterPlasticCup extends PlasticCup{

	public void drink() {
		System.out.println("我塑料杯喝水");	
	}	
}
//塑料饮料杯
class DrinksPlasticCup extends PlasticCup{

	public void drink() {
		System.out.println("我塑料杯喝饮料");	
	}	
}


//分析  以上分别是  两个抽象类  分别是塑料杯   玻璃杯   
// 根据他们的特征  都能装水和饮料    分为  水和饮料两个产品族 
//  建造两个工厂     
//抽象工厂   不管是玻璃杯还是塑料杯  都能生产水杯和饮料杯
abstract class CupFactory{
	public abstract   GlassCup   createGlassCup();
	public abstract   PlasticCup   createPlasticCup();
}


//实现水杯工厂
class WaterCupFactory extends CupFactory{

	@Override
	public GlassCup createGlassCup() {
		return new WaterGlassCup();
	}

	@Override
	public PlasticCup createPlasticCup() {
		return new WaterPlasticCup();
	}
	}
//实现饮料杯工厂
class DrinkFactory extends CupFactory{

	@Override
	public GlassCup createGlassCup() {
		return new DrinksGlassCup();
	}

	@Override
	public PlasticCup createPlasticCup() {
		return new DrinksPlasticCup();
	}

}	

class Factory{
	public static void main(String[] args) {
		//这里我想要买一个水杯,最好是玻璃的
		CupFactory cupFactory = new WaterCupFactory();  //喝水建造水工厂
		GlassCup cup = cupFactory.createGlassCup();   //玻璃水杯
	}
}

如上代码所示,跟上面车的描述类似 ,装水和饮料是玻璃杯和塑料杯的特征,超级跑车和商务车也是奥利,奔驰等车的"特征",所以把特征区别不同族的产品,每一个产品族建造一个工厂,生产不同类型、牌子的产品,这就是抽象工厂模式。 但是抽象工厂也有缺点,如果,我们增加了一个新的产品树,也就是增加一个新的产品的牌子,除了要增加这个产品不同族的类之外,还要更改产品族工厂的代码,这样改动量太大,不太可取。所以下面我们将对抽象工厂进行改进,使用反射+简单工厂的方式来改进,但是这种方式的思想跟java设计模式中的策略模式很接近,所以放到下一节策略模式叙述。

四 、三种工厂模式的区别

简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品,增加产品需要修改工厂判断逻辑代码)

工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品,增加产品不需要更改逻辑代码,子需要增加相应的工厂类,但容易造成工厂类冗余。)

抽象工厂 :用来生产不同产品族的全部产品。(不支持拓展增加产品;支持增加产品族,可以改善工厂方法工厂类冗余的问题,但是增加产品的话,需要修改的代码较多,比如上面所讲增加一个汽车品牌的话,不仅要增加产品类,还要修改增加工厂方法)

五、注意事项

(1)工厂类常常采用单例模式(Singleton)。

(2)工厂类拥有基类(定义共同接口),基类可以为纯虚类,也可以定义缺省方法。

(3)对于工厂方法和抽象工厂,基类中的生产产品的函数常常为虚函数,以实现动态绑定。

(4)如果要把工厂方法当作参数作函数传递时,尽量使用其指针或引用,这样可以实例不同的工厂方法使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值