面向對象的設計要遵循幾項基本原則:
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();
}
}
這種模式有個前提,那就是不能增加某個產品,而只能增加一個產品族。