【设计模式-4】工厂模式(简单工厂,工厂方法,抽象工厂)

简单工厂模式(Simple Factory)


 

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。创建在一个类中,客户无需知道具体产品的名称,只需要知道产品类所对应的参数即可。但是工厂的职责过重,而且当类型过多时不利于系统的扩展维护。

简单工厂模式参与者:

工厂角色(Creator) 简单工厂模式的核心,其他类调用通过调用它,实现创建所有具体产品类的实例(一个)
抽象产品角色(Product) 定义简单工厂创建的对象的父类或它们共同拥有的接口。可以是一个类、抽象类或接口。(一个)
具体产品角色(Concrete Product) 继承自抽象产品角色,有几个产品从抽象产品类派生几个具体产品的子类(多个)

例子:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


//抽象产品角色(Product)
public interface Fruit
{
	void DebugTaste();
} 

//具体产品角色(Concrete Product)
public class Banana:Fruit
{
	public void DebugTaste()
	{
		Debug.Log("香蕉甜的");
	}
}

//具体产品角色(Concrete Product)
public class Orange:Fruit
{
	public void DebugTaste()
	{
		Debug.Log("橘子酸的");
	}
}

//工厂角色(Creator)
public class Factory
{
	public Fruit CreateFruit(string _fruitName)
	{
		Fruit tempFruit = null;
		switch(_fruitName)
		{
			case "banana":
			{
				tempFruit = new Banana();
				break;
			}
			case "orange":
			{
				tempFruit = new Orange();
				break;
			}
		}
		return tempFruit;
	}
}

public class Client: MonoBehaviour {

	// Use this for initialization
	void Start () {
		Factory tempFactory = new Factory();
		Fruit tempBanana = tempFactory.CreateFruit("banana");
		tempBanana.DebugTaste();
		Fruit tempOrange = tempFactory.CreateFruit("orange");
		tempOrange.DebugTaste();
	}
}

简单工厂模式最大的优点在于实现对象的创建和对象的使用分离,将对象的创建交给专门的工厂类负责,但是其最大的缺点在于工厂类不够灵活,增加新的具体产品需要修改工厂类的判断逻辑代码,违反开放关闭原则。而且产品较多时,工厂方法代码将会非常复杂。


工厂产品模式(Factory Method) 

工厂方法模式在简单工厂模式的基础上增加一个抽象工厂,派生出多种工厂,按需选择一工厂生成对象。这些工厂之间靠拥有同一接口方法关联,所以叫“工厂方法”模式,工厂方法让类把实例化推迟到子类。

工厂产品模式参与者:

抽象产品角色(Product) 定义产品的接口(一个)
具体产品角色(ConcreteProduct) 实现接口Product的具体产品类(多个)
抽象工厂角色(Creator) 声明工厂方法(FactoryMethod),返回一个产品(一个)
具体工厂(ConcreteCreator) 实现FactoryMethod工厂方法,由客户调用,返回一个产品的实例(多个)

//抽象产品角色(Product)
public interface Fruit
{
	void DebugTaste();
} 

//具体产品角色(Concrete Product)
public class Banana:Fruit
{
	public void DebugTaste()
	{
		Debug.Log("香蕉甜的");
	}
}

//具体产品角色(Concrete Product)
public class Orange:Fruit
{
	public void DebugTaste()
	{
		Debug.Log("橘子酸的");
	}
}

//抽象工厂角色 (Creator)
public abstract class IFactory 
{
	public abstract Fruit CreateFactoryMethod();
} 

//具体工厂(ConcreteCreator)只出产圆形的水果
public class RoundnessFactory:IFactory
{
	public override Fruit CreateFactoryMethod()
	{
		return new Orange();
	}
}

//具体工厂(ConcreteCreator)只出产条形的水果
public class BarFactory:IFactory
{
	public override Fruit CreateFactoryMethod()
	{
		return new Banana();
	}
}


public class Client: MonoBehaviour {

	// Use this for initialization
	void Start () {
		//具体产品工厂
		IFactory tempRoundnessFactory = new RoundnessFactory();
		IFactory tempBarFactory = new BarFactory();
		//具体产品工厂创建出具体产品
		Fruit tempOrange = tempRoundnessFactory.CreateFactoryMethod();
		tempOrange.DebugTaste();
		Fruit tempBanana = tempBarFactory.CreateFactoryMethod();
		tempBanana.DebugTaste();
	}
}

工厂方法模式相当于在简单工厂模式的基础上增加一个抽象工厂,在简单工厂模式下如果增加一个产品,要修改工厂类,不符合开闭原则。在工厂方法下,只需要增加具体工厂和具体产品即可。

1、优点

  1. 符合“开闭”原则,具有很强的的扩展性、弹性和可维护性。扩展时只要添加一个ConcreteCreator(具体工厂),而无须修改原有的ConcreteCreator,因此维护性也好。解决了简单工厂对修改开放的问题。
  2. 使用了依赖倒置原则,依赖抽象而不是具体,使用(客户)和实现(具体类)松耦合。
  3. 客户只需要知道所需产品的具体工厂,而无须知道具体工厂的创建产品的过程,甚至不需要知道具体产品的类名。

2、缺点

  1. 一个具体产品对应一个类,当具体产品过多时会使系统类的数目过多,增加系统复杂度。
  2. 每增加一个产品时,都需要一个具体类和一个具体创建者,使得类的个数成倍增加,导致系统类数目过多,复杂性增加。
  3. 对简单工厂,增加功能修改的是工厂类;对工厂方法,增加功能修改的是客户端。

抽象工厂模式(Abstract Factory

多个抽象产品和多个抽象工厂派生出多个具体产品和具体工厂, 每个具体工厂中根据需要产出不同组合的具体产品。多种工厂协作,生成多种class关系不大的对象。常见的处理是把这些对象整体打包提供给你。

抽象工厂模式参与者:

抽象产品角色(Product) 定义产品的接口(多个)
具体产品角色(ConcreteProduct) 实现接口Product的具体产品类(多个)
抽象工厂角色(Creator) 声明工厂方法(FactoryMethod),返回一个产品(一个)
具体工厂(ConcreteCreator) 实现FactoryMethod工厂方法,由客户调用,返回一个产品的实例(多个)
//抽象产品角色(Product)
public interface Fruit
{
	void DebugTaste();
} 

//具体产品角色(Concrete Product)
public class Banana:Fruit
{
	public void DebugTaste()
	{
		Debug.Log("香蕉");
	}
}

//具体产品角色(Concrete Product)
public class Orange:Fruit
{
	public void DebugTaste()
	{
		Debug.Log("橘子");
	}
}

//抽象产品角色(Product)
public interface Drink
{
	void DebugTaste();
} 

//具体产品角色(Concrete Product)
public class BlackTea:Drink
{
	public void DebugTaste()
	{
		Debug.Log("红茶");
	}
}

//具体产品角色(Concrete Product)
public class Milk:Drink
{
	public void DebugTaste()
	{
		Debug.Log("牛奶");
	}
}

//抽象工厂角色 (Creator) 组合多个具体产品
public abstract class IFactory 
{
	public abstract Fruit GetFruit();
	public abstract Drink GetDrink();
} 

//具体工厂(ConcreteCreator)产出 = 香蕉 + 牛奶
public class Factory1:IFactory
{
	public override Fruit GetFruit()
	{
		return new Banana();
	}
	public override Drink GetDrink()
	{
		return new Milk();
	}
}

//具体工厂(ConcreteCreator)产出 = 橘子 + 红茶
public class Factory2:IFactory
{
	public override Fruit GetFruit()
	{
		return new Orange();
	}
	public override Drink GetDrink()
	{
		return new BlackTea();
	}
}


public class Client: MonoBehaviour {

	// Use this for initialization
	void Start () {
		IFactory tempIfactory1 = new Factory1();
		tempIfactory1.GetDrink().DebugTaste();
		tempIfactory1.GetFruit().DebugTaste();

		IFactory tempIfactory2 = new Factory2();
		tempIfactory2.GetDrink().DebugTaste();
		tempIfactory2.GetFruit().DebugTaste();
	}
}

1、优点

  1.  允许客户使用抽象的接口创建一组相关产品,而不需要知道(或者关心)产出的具体产品是什么,这样客户就可以从具体的产品中解耦出来。
  2.  一个具体工厂可以创建多个产品,与工厂方法模式相比,可以少产生具体工厂的类数量。
  3.  易于交换产品系列,只要更换具体工厂,就可以改变这个产品系列。

2、缺点

  1.  抽象工厂是使用组合的方式把工厂方法集合到一个类中,当新增一个产品家族成员时就要修改抽象工厂类及其下面的具体工厂类,所以它的扩展性比较差。
  2.  每新增一个产品子类都要创建一个类,当产品子类过多时会产生很多类,导致系统复杂性加大。

参考:

http://www.unity.5helpyou.com/2534.html

https://www.zhihu.com/question/27125796

https://www.cnblogs.com/toutou/p/4899388.html#_label3

https://blog.csdn.net/superbeck/article/details/4446177

猜你喜欢

转载自blog.csdn.net/qq_19269527/article/details/84553409