2017-01-13 10 views
1

Я learnig простого шаблона фабрики, и я хотел бы знать, если все методы моей фабрики действительны для такой схемы:Все ли эти сигнатуры метода действительны для простого шаблона фабрики?

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

@Pace Я бы сказал, что http://codereview.stackexchange.com/, вероятно, будет лучше. –

+1

@Pace при обращении к другим сайтам часто бывает полезно указать, что [перекрестная публикация неодобрительно] (http://meta.stackexchange.com/tags/cross-posting/info) – gnat

ответ

0

Все зависит от того, для чего будет использоваться ваша фабрика.

1) Если вы собираетесь передать эту фабрику на какой-то общий instantiator, то ваш завод должен реализовать некоторый интерфейс, общий для всех заводов, используемых этим мастером. Этот интерфейс может иметь один метод типовые варианты:

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, чтобы сначала проверить, какой вариант является righ? Или я должен создать специализированную BmwCarFactory, которая работает непосредственно с BmwCarOptions? – adragomir

+0

Вы можете использовать 'instanceof', как только знаете, это тип« BMW », чтобы увидеть, используем ли мы« BMWCarOptions », или вы можете создать другую фабрику. –

+0

Боюсь, вам нужно создать 'CarOptionsFactory', чтобы создать всевозможные опции :) –