2017-01-13 36 views
1

我的主義學習簡單工廠模式,我想知道如果我廠所有的方法都是有效的這樣一種模式:所有這些方法簽名是否適用於簡單工廠模式?

public class Bmw implements Car { 
private String color; 
private boolean hasXDrive; 

public Bmw() { 
} 

public Bmw(String color) { 
    this.color = color; 
} 

public Bmw(String color, boolean hasXDrive) { 
    this.color = color; 
    this.hasXDrive = hasXDrive; 
} 

public String getColor() { 
    return color; 
} 

public void setColor(String color) { 
    this.color = color; 
} 

public boolean isHasXDrive() { 
    return hasXDrive; 
} 

public void setHasXDrive(boolean hasXDrive) { 
    this.hasXDrive = hasXDrive; 
} 
} 


public class Audi implements Car { 
private String color; 
private int turnAssistLevel; 

public Audi() { 
} 

public Audi(String color) { 
    this.color = color; 
} 

public Audi(String color, int turnAssistLevel) { 
    this.color = color; 
    this.turnAssistLevel = turnAssistLevel; 
} 

public String getColor() { 
    return color; 
} 

public void setColor(String color) { 
    this.color = color; 
} 

public int getTurnAssistLevel() { 
    return turnAssistLevel; 
} 

public void setTurnAssistLevel(int turnAssistLevel) { 
    this.turnAssistLevel = turnAssistLevel; 
} 
} 


public class SimpleCarFactory { 

// 1. make empty cars 
public Car makeCar(CarType carType) { 
    switch (carType) { 
     case AUDI: 
      return new Audi(); 
     case BMW: 
      return new Bmw(); 
     default: 
      throw new RuntimeException("No such car type!"); 
    } 
} 

// 2. make cars with colors 
public Car makeCarWithColor(CarType carType, String color) { 
    switch (carType) { 
     case AUDI: 
      return new Audi(color); 
     case BMW: 
      return new Bmw(color); 
     default: 
      throw new RuntimeException("No such car type!"); 
    } 
} 

// 3. BMW has an option that differentiate it from any other car. We cannot use a general car factory anymore 
public Car makeBmw(String color, boolean hasXDrive) { 
    return new Bmw(color, hasXDrive); 
} 

// 4. Audi has a turnAssistLevel option 
public Car makeAudi(String color, int turnAssistLevel) { 
    return new Audi(color, turnAssistLevel); 
} 

// 5. The same as #1, only it is static now make empty cars 
public static Car staticMakeCar(CarType carType) { 
    switch (carType) { 
     case AUDI: 
      return new Audi(); 
     case BMW: 
      return new Bmw(); 
     default: 
      throw new RuntimeException("No such car type!"); 
    } 
} 
} 

我在代碼中添加註釋的方法的變體。我問這些問題,因爲通常情況下,你創建一個基於一些鑑別器(CarType)的子類。但是你也可以有構造函數參數。

此外,我不知道當你的相關對象有不同的構造函數時該怎麼辦。

請告訴我SimpleCarFactory的哪些方法符合簡單的工廠模式?

親切的問候,

+0

您可能會在http://softwareengineering.stackexchange.com/ – Pace

+1

@Pet上得到更好的答案我會說http://codereview.stackexchange.com/可能會更好。 –

+1

@Pace在引用其他網站時,通常很有幫助的一點是[交叉發佈是皺眉了](http://meta.stackexchange.com/tags/cross-posting/info) – gnat

回答

0

這一切都取決於你的工廠將用於什麼。 1)如果你打算把這個工廠傳遞給一些通用的實例化器,那麼你的工廠必須實現該實例化器使用的所有工廠通用的一些接口。這個接口很可能有一個方法與一般的選項:

public interface CarFactory { 
    Car makeCar(CarOptions options); 
} 

2)如果你想從你的代碼的不同部分調用你的工廠「手動」,那麼我會說你的做法是正確的。 makeAudi("red", true)看起來比makeCar(new CarOptions(CarType.AUDI, "red", ...))更可讀。

0

「他們有效」是的。

「他們是最佳的」沒有。

您不會重載方法,我認爲這有助於解決您的問題。

public Car makeCar(CarType carType) 
       throws NoCarExistsException 
public Car makeCar(CarType carType, Color color) 
       throws NoCarExistsException 
public Car makeCar(CarType carType, Color color, Options options) 
       throws NoCarExistsException 
// where Options is a container class with hashmap 
// (or one of many other valid impl. possibilities) with all the options. 

而只是「所有選項組合都存在」的所有邏輯都在工廠邏輯中。

也可以'顏色'也是'選項'。


注:這樣做的好處是,工廠的用戶可以只讓他們想要的選項列表,要麼得到汽車或異常。使用起來更簡單,但意味着邏輯必須存在於工廠(我認爲它應該是),而不是依賴用戶必須編寫額外的邏輯才能夠工廠。

2

我會創建一個CarOptions對象並使用它,而不是有這麼多不同的方法。

public class CarOptions { 
    private String color; 
    private CarType carType; 

    public String getColor() { 
     return this.color; 
    } 

    public void setColor(String color) { 
     this.color = color; 
    } 

    public CarType getCarType() { 
     return this.carType; 
    } 

    public void setCarType(CarType carType) { 
     this.carType = carType; 
    } 
} 

然後簡單makeCar方法,該方法取CarOptions對象。

public Car makeCar(CarOptions options) { 
    switch (options.getCarType()) { 
     case AUDI: 
      return new Audi(options.getColor()); 
     case BMW: 
      return new Bmw(options.getColor()); 
     default: 
      throw new RuntimeException("No such car type!"); 
    } 
} 

這樣做的好處是,你可以創建一個BMWCarOptions類:

public class BMWCarOptions extends CarOptions { 
    private boolean hasXDrive; 

    public boolean getHasXDrive() { 
     return this.hasXDrive; 
    } 

    public void setHasXDrive(boolean hasXDrive) { 
     this.hasXDrive = hasXDrive; 
    } 
} 

,則仍可傳遞到makeCar方法這一點。

+0

好吧,如果我這樣做,我必須修改makeCar來首先檢查什麼樣的選項是正確的?或者我應該創建一個直接與BmwCarOptions一起工作的專用BmwCarFactory? – adragomir

+0

您可以在知道它是'寶馬'類型時使用'instanceof'來查看我們是否使用了'BMWCarOptions',或者您可以創建另一個工廠。 –

+0

恐怕你必須創建'CarOptionsFactory'然後創建各種選項:) –