設計模式系列之二:工廠模式

      面向對象的設計要遵循幾項基本原則:

OCP(open-closed principle ):開閉原則,一個類的實體應該對擴展開放,對修改關閉。

DIP(dependence invers princip):依賴倒轉原則,要針對接口編程,而不是針對實現編程。

LOD(low of demeter):迪米特法則:只與你直接的朋友通訊,而不與陌生人通訊。    工廠模式主要分三種,簡單工廠模式,工廠方法模式和抽象工廠模式。

    工廠模式也是設計模式中最常用的模式之一,工廠模式的主要目的是要使調用者和構建者分離,具體優點有:

    可以使代碼結構清晰,有效的封裝變化。在編程中,產品類的實例化有事是複雜多變的。通過把實例化過程封裝,是的調用者根本無需關心產品的實例化過程,只需要通過方法調用到需要的類。

對調用者屏蔽具體的產品類,使用工廠類,調用者只要關心調用的接口,即使具體的實現過程發生變化,對調用者也沒有影響。

降低耦合度。

    簡單工廠模式

在一般的情況下,我們在一個類中調用另一個類時需要通過實例化需要的類來調用,這時候調用者參與了實體類實例化的構造,增加了耦合         度,工廠模式就是要把這種實例化類的過程重新包裝起來,調用者只需調用工廠的某個方法邊能獲取類的實例化對象。

我們有一個汽車接口

package com.panda.com.simpleFactory;

public interface Car {
	void run();
}
分別有兩個汽車來實現

package com.panda.com.simpleFactory;

public class Byd implements Car {
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("比亞迪車");
	}
}

package com.panda.com.simpleFactory;

public class Bmw implements Car {
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("寶馬車");
	}
}
和一個工廠類
package com.panda.com.simpleFactory;

public class Factory {
	public static Car getcar(String car){
		if("寶馬".equals(car)){
			return new Bmw();
		}else if("比亞迪".equals(car)){
			return new Byd();
		}else{
			return null;
		}
		
	}
}
然後可以通過這個工廠類來調用靜態方法得到實例化的對象

package com.panda.com.simpleFactory;
/**
 * 簡單工廠模式
 * @author Administrator
 *
 */
public class UseCar {
	public static void main(String[] args) {
		Car car1 = Factory.getcar("寶馬");
		Car car2 = Factory.getcar("比亞迪");
		car1.run();
		car2.run();
	}
}

如果增加新的實體類的汽車,只需要在工廠類中添加合適的條件和返回值,而調用者的方法不會改變。

當然,如果仔細觀察我們就會發現這個違反了OCP原則,因爲涉及到修改工廠類的代碼,違反了只能擴展,不能修改的原則。

工廠方法模式

所謂工廠方法就是爲每一個實體類寫一個對應工廠類,當調用者調用時就可以直接按照各自的工廠方法進行調用。如例

寫一個工廠接口

package com.panda.com.factoryMethod;

public interface Factory {
	Car getCar();
}
然後爲每個實體類寫一個實現工廠接口的對應的工廠類

package com.panda.com.factoryMethod;

public class BmwFactory implements Factory {

	@Override
	public Car getCar() {
		return new Bmw();
	}
}
package com.panda.com.factoryMethod;


public class BydFactory implements Factory {


	@Override
	public Car getCar() {
		return new Byd();
	}
}

這樣在調用時這些使用工廠類的對象來調用方法就可以

package com.panda.com.factoryMethod;
/**
 * 工廠方法模式
 * @author Administrator
 */
public class UseCar {
	public static void main(String[] args) {
		Car car1 = new BmwFactory().getCar();
		Car car2 = new BydFactory().getCar();
		car1.run();
		car2.run();
	}
}

對比簡單工廠模式,工廠方法完美的避免了修改原有代碼這一準則,但是同時,當我們新建實體類時卻要寫一個相對應的工廠類,實體類多起來後,類的數量會比較臃腫,所以兩相對比,雖然簡單工廠模式稍微違反了OCP準則,但在實際開發中,簡單工廠模式更加常用。

抽象工廠模式

抽象工廠模式完全有別於前兩種工廠模式,因爲抽象工廠是對於一個產品族而言的,所謂產品族,就是組成一個完整產品的各部件。例如一個汽車是有發動機,車體,輪胎,座椅,內飾等等組成,這些組件就是一個產品族。

我們現就以一個發動機,座椅,輪胎爲一個產品族用代碼實現抽線工廠模型

package com.panda.com.abstractFactory;

public interface Engin {
	void run();
}

class goodEngin implements Engin{

	@Override
	public void run() {
		System.out.println("跑得快");
	}
	
}
class badEngin implements Engin{
	
	@Override
	public void run() {
		System.out.println("跑得慢");
	}
	
}

package com.panda.com.abstractFactory;

public interface Seat {
	void massage();
}

class goodSeat implements Seat{

	@Override
	public void massage() {
		System.out.println("有按摩功能");
	}
	
}
class badSeat implements Seat{
	
	@Override
	public void massage() {
		System.out.println("沒有按摩功能");
	}
	
}

package com.panda.com.abstractFactory;

public interface Tyre {
		void revoles();
}

class goodTyre implements Tyre{

	@Override
	public void revoles() {
		// TODO Auto-generated method stub
		System.out.println("質量好");
	}
	
}
class badTyre implements Tyre{
	
	@Override
	public void revoles() {
		// TODO Auto-generated method stub
		System.out.println("質量差");
	}
	
}
然後是一個抽象工廠接口和一個工廠實現類
package com.panda.com.abstractFactory;

public interface Factory {
	Engin getEngin();
	Seat getSeat();
	Tyre getTyre();
}
package com.panda.com.abstractFactory;


public class GoodCarFactory implements Factory{


	@Override
	public Engin getEngin() {
		// TODO Auto-generated method stub
		return new goodEngin();
	}


	@Override
	public Seat getSeat() {
		// TODO Auto-generated method stub
		return new goodSeat();
	}


	@Override
	public Tyre getTyre() {
		// TODO Auto-generated method stub
		return new goodTyre();
	}


}
最後調用者用工廠調用
package com.panda.com.abstractFactory;

public class Client {

	/**
	 * 抽象工廠模式
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Factory factory = new GoodCarFactory();
		Engin en = factory.getEngin();
		en.run();
	}

}

這種模式有個前提,那就是不能增加某個產品,而只能增加一個產品族。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章