2012-03-29 73 views
0

我真的沒有太多使用設計模式的經驗。我想我需要在我的情況下使用Abstract Factory Pattern如何改進我的抽象工廠模式?

我正在創建一個系統來產生數學問題。開發人員必須實現兩個接口:

  • 問題:這包含需要生成問題的屬性。
  • 配置:這是生成問題的範圍參數或條件。
  • 工廠:他有創造新問題的傾向。

這是什麼意思?它意味着像一個黑匣子。輸入是Configuration,輸出是Problem,中間的接口是工廠。

enter image description here

這裏我有我的界面和標記接口:

public abstract class Problem { } 
public abstract class Configuration { } 
public interface IProblemFactory 
{ 
    Problem CreateProblem(); 
} 

這是工廠基地,因爲我需要Random類。我的所有實現這個的類都必須具有相同的種子,所以我有一個靜態實例。

public abstract class ProblemBaseFactory<TProblem, TConfiguration> : IProblemFactory 
    where TProblem : Problem 
    where TConfiguration : Configuration 
{ 
    private const int DEFAULT_SEED = 100; 
    protected TConfiguration _config; 
    private static Random _random; 

    public ProblemBaseFactory() { } 
    public ProblemBaseFactory(TConfiguration config) 
    { 
     _config = config; 

     if (_random == null) _random = new Random(DEFAULT_SEED); 
    } 

    protected TConfiguration Configuration { get { return _config; } } 
    protected Random Random { get { return _random; } } 

    public void SetSeed() 
    { 
     _random = new Random(DEFAULT_SEED); 
    } 

    public Problem CreateProblem() 
    { 
     return CreateProblem(_config); 
    } 

    public abstract TProblem CreateProblem(TConfiguration config); 
} 

然後我實現了所有這些。例如,這是一個BinaryProblems模塊,如2+3

public class BinaryConfiguration : Configuration 
{ 
    public Range<int> Range1 { get; set; } 
    public Range<int> Range2 { get; set; } 
    public List<Operators> Operators { get; set; } 

    public BinaryConfiguration(Range<int> range1, Range<int> range2, List<Operators> operators) 
    { 
     this.Range1 = range1; 
     this.Range2 = range2; 
     this.Operators = operators; 
    } 

public class BinaryProblem : Problem 
{ 
    public BinaryProblem(decimal x, decimal y, Operators op, decimal response) 
    { 
     this.X = x; 
     this.Y = y; 
     this.Response = response; 
    } 

    public decimal X { get; private set; } 
    public decimal Y { get; private set; } 
    public decimal Response { get; private set; } 
} 

public enum Operators 
{ 
    Addition, Substract, Multiplication, Division 
} 

而最重要的部分,這裏是一個具體的工廠。看看這部分我設置了通用值。爲什麼?因爲我認爲這是實現具體價值的最佳方式,我的意思是我現在不必施加任何價值。

public class BinaryFactory : ProblemBaseFactory<BinaryProblem, BinaryConfiguration> 
{ 
    public BinaryFactory(BinaryConfiguration config) : base(config) { } 

    public override BinaryProblem CreateProblem(BinaryConfiguration config) 
    { 
     var x = GenerateValueInRange(config.Range1); 
     var y = GenerateValueInRange(config.Range2); 

     var index = Random.Next(config.Operators.Count); 
     var op = config.Operators[index]; 

     return new BinaryProblem(x, y, op, x + y); 
    } 

    private decimal GenerateValueInRange(Range<int> range) 
    { 
     return Random.Next(range.Min, range.Max); 
    } 
} 

並實現它是:

 BinaryConfiguration configuration = new BinaryConfiguration() {.. } 
     IProblemFactory factory = new BinaryFactory(configuration); 
     var a = factory.CreateProblem(); 

但在這一點上,我想這是不是最好的設計..因爲如果我想用一個新的配置,我應該創建另一個實例的,我認爲這不是最好的。

我該如何改進?

+2

諷刺嗎?擺脫摘要和接口。 – 2012-03-29 01:19:09

+1

這可能會更好地匹配[代碼評論](http://codereview.stackexchange.com),因爲您實際上並沒有遇到代碼問題。 – 2012-03-29 01:47:54

+0

這與CodeReview上的問題類似嗎? http://codereview.stackexchange.com/questions/8647/how-to-add-a-new-feature-to-this-factory-model – dreza 2012-03-29 01:56:38

回答

1

作爲一個起點,我建議你使用遞歸類型定義。試試這個:

public abstract class Problem<P, C> 
    where P : Problem<P, C> 
    where C : Configuration<P, C> 
    { } 

public abstract class Configuration<P, C> 
    where P : Problem<P, C> 
    where C : Configuration<P, C> 
    { } 

public interface IProblemFactory<P, C> 
    where P : Problem<P, C> 
    where C : Configuration<P, C> 
{ 
    P CreateProblem(C configuration); 
} 

這有效地實現了你的類型的四人幫「橋」設計模式。

讓我知道這是否有幫助。

+0

對不起,我應該只使用最後一個,對不對? – 2012-03-29 03:51:07

+0

@DarfZon - 不,你需要三個人。 – Enigmativity 2012-03-29 11:38:15