2016-07-29 4 views
0

Я пытаюсь создать фабрику, которая создает классы, которые используют один и тот же базовый класс (или интерфейс), но конкретные заводы нуждаются в разных наборах параметров. Если чувствуете, что я делаю что-то неправильно, потому что эти разные Enums требуют дополнительного кода. Это можно сделать лучше?Реализации фабричных шаблонов с различными параметрами

Классы должны быть созданы:

public interface IShapeData {} 

public abstract class ShapeDataWithCorners : IShapeData 
{ 
    public double Width { get; set; } 
} 

class Square : ShapeDataWithCorners {} 

class Rectangle : ShapeDataWithCorners 
{ 
    public double Height { get; set; } 
} 

class Circle : IShapeData 
{ 
    public double Radius { get; set; } 
} 

class Oval : IShapeData 
{ 
    public double Radius1 { get; set; } 
    public double Radius2 { get; set; } 
} 

Заводы:

public enum RoundShapeTypes 
{ 
    Circle, 
    Oval 
} 

public enum CornerShapeTypes 
{ 
    Square, 
    Rectangle 
} 

public class RoundShapeDataFactory : IShapeDataFactory 
{ 
    private readonly RoundShapeTypes m_shapeType; 

    public RoundShapeDataFactory (RoundShapeTypes shapeType) 
    { 
     m_shapeType = shapeType; 
    } 

    public IShapeData CreateShapeData() 
    { 
     switch (m_shapeType) 
     { 
      case RoundShapeTypes.Circle: 
       return new Circle(); 
      case RoundShapeTypes.Oval: 
       return new Oval(); 
     } 
    } 
} 

public class CornerShapeDataFactory : IShapeDataFactory 
{ 
    private readonly CornerShapeTypes m_shapeType; 

    public CornerShapeDataFactory (CornerShapeTypes shapeType) 
    { 
     m_shapeType = shapeType; 
    } 

    public IShapeData CreateShapeData() 
    { 
     switch (m_shapeType) 
     { 
      case CornerShapeTypes.Square: 
       return new Square(); 
      case CornerShapeTypes.Rectangle: 
       return new Rectangle(); 
     } 
    } 
} 

Классы, которые называют завод:

public class RoundShapeManager 
{ 
    public IShapeData CurrentShapeData{get; set; } 

    public void SetShapeType (RoundShapeTypes shapeType) 
    { 
     RoundShapeDataFactory factory = new RoundShapeDataFactory (shapeType); 
     CurrentShapeData = factory.CreateShapeData(); 
    } 
} 

public class CornerShapeManager 
{ 
    public IShapeData CurrentShapeData {get; set; } 

    public void SetShapeType (CornerShapeTypes shapeType) 
    { 
     CornerShapeDataFactory factory = new CornerShapeDataFactory (shapeType); 
     CurrentShapeData = factory.CreateShapeData(); 
    } 
} 

Эти "менеджеры" являются на самом деле WPF ViewModels, которые могут изменить их представитель отображал данные во время выполнения. Для краткости я удалил конкретный код viewmodel.

+0

Это может быть хороший вопрос для [codereview.se] – null

+1

Я только что оставил комментарий, а не закрыл голос. Поскольку закрытое голосование за «слишком широкое», я предполагаю, что это связано с тем, что ваш вопрос открыт, что справедливо для CR, но не на SO (см. Таблицу в принятом ответе в метафоном, с которым вы связались). В том же абзаце, что и строка, которую вы цитировали: «Вместо этого проголосуйте, чтобы закрыть как слишком широкий или в основном основанный на мнениях». – null

ответ

1

Вы можете уменьшить его к этому:

public interface IShapeData { } 

public abstract class ShapeDataWithCorners : IShapeData 
{ 
    public double Width { get; set; } 
} 

public class Square : ShapeDataWithCorners { } 

public class Rectangle : ShapeDataWithCorners 
{ 
    public double Height { get; set; } 
} 

public class Circle : IShapeData 
{ 
    public double Radius { get; set; } 
} 

public class Oval : IShapeData 
{ 
    public double Radius1 { get; set; } 
    public double Radius2 { get; set; } 
} 

public enum ShapeType 
{ 
    Circle, 
    Oval, 
    Square, 
    Rectangle 
} 

public interface IShapeDataFactory 
{ 
    IShapeData CreateShapeData(ShapeType shapeType); 
} 

public class ShapeDataFactory : IShapeDataFactory 
{ 
    public IShapeData CreateShapeData(ShapeType shapeType) 
    { 
     switch (shapeType) 
     { 
      case ShapeType.Circle: 
       return new Square(); 
      case ShapeType.Oval: 
       return new Oval(); 
      case ShapeType.Rectangle: 
       return new Rectangle(); 
      case ShapeType.Square: 
       return new Square(); 
      default: 
       throw new ArgumentException("invalid shape type"); 
     } 
    } 
} 

Так один завод, один перечисление всех типов фигур, и вы можете иметь один менеджер, который в основном делает это:

IShapeDataFactory s = new ShapeDataFactory(); 
IShapeData temp = s.CreateShapeData(ShapeType.Square); 
+0

Отдельные перечисления должны были использоваться для представления правильных параметров в пользовательском интерфейсе. Я полагаю, что конверсия может произойти на стороне пользовательского интерфейса, чтобы использовать единое перечисление при вызове фабрики. – kbeal2k

+0

Это имеет смысл. Параметры, указывающие фабрике, тип возвращаемого типа принадлежат методу 'Create' (как показано в ответе), а не в конструкторе для фабрики. Если класс должен знать, какие аргументы конструктора переходят на завод, тогда класс стал ответственным за создание фабрики, которая побеждает цель завода. –

+0

@ScottHannen - согласился. Ответственность лежит только на фабрике, а не на обертке вокруг завода. – Ric

Смежные вопросы