2012-03-24 92 views
0

肯定這不是最好的標題。我正在創建一個系統來產生數學問題。開發人員必須實現兩個接口:如何維持兩個班級之間的溝通?

  • Problem:這包含需要生成問題的屬性。
  • Configuration:這是生成Problem的範圍參數。

這些接口:

public abstract class Problem 
{ 
} 

public abstract class Configuration 
{ 
} 

enter image description here

這裏是爲BinaryProblem一個例子。

public class BinaryProblem : Problem 
{ 
    public decimal X { get; set; } 
    public decimal Y { get; set; } 

    public BinaryProblem(decimal x, decimal y) 
    { 
     this.X = x; // Number 1 
     this.Y = y; // Number 2 
    } 
} 

public class BinaryProblemConfiguration : Configuration 
{ 
    // Range for X 
    public int XMin { get; set; } 
    public int XMax { get; set; } 

    // Range for Y 
    public int YMin { get; set; } 
    public int YMax { get; set; } 

    public BinaryProblemConfiguration() { } 
} 

你能看到問題與配置之間的界限嗎?我需要放置許多實現這兩個接口的模塊。

所以,我需要一種方法來生成它們。我想在創建一個抽象類,其中包含:

  • protected static Random:幾乎所有的配置需要一個隨機的類來創建數字(即random.Next(X1, Y1);)。而且必須是靜態的,因爲需要始終使用相同的種子創建數字。
  • public abstract TProblem Generate(TConfiguration config); // where : TProblem : Problem, new(), TConfiguration : Configuration

和實施的每個問題類型這個抽象類。

我的問題是:這是一個開始解決這個解決方案的好方法,還是我必須做的其他解決方案?

編輯:我試圖一個例子是:

這是我的抽象類,我的意思是我的想法是,當你實例化這個類,您所指定的通用值:

public interface IProblemFactory 
{ 
    Problem CreateProblem(); 
} 

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

    public ProblemBaseFactory(TConfiguration config) 
    { 
     _config = config; 

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

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

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

    public abstract TProblem CreateProblem(TConfiguration config); 
} 

public class BinaryProblemFactory : ProblemBaseFactory<BinaryProblem, BinaryProblemConfiguration> 
{ 
    public override BinaryProblem CreateProblem(BinaryProblemConfiguration config) 
    { 
     var x = GenerateValueInRange(_config.Range1); 
     var y = GenerateValueInRange(_config.Range2); 
     return new BinaryProblem(x, y, Operators.Addition); 
    } 

    private decimal GenerateValueInRange(Range<int> range) 
    { 
     return _random.Next(range.MinValue, range.MaxValue); 
    } 
} 
+0

Sorr,我不明白如何從'問題'和'配置'派生的類應該使用。你可以添加一個使用的例子嗎? – MiMo 2012-03-24 00:51:50

+0

爲什麼X,X1和Y1的範圍以及Y,X2,Y2的範圍。 Yech!使用XMin和XMax等。 – 2012-03-24 01:19:03

+0

我已添加新信息:) – 2012-03-24 17:15:11

回答

2

我認爲這是很好的合起來使用聚合值。在你的案例對象範圍將是有用的。喜歡的東西(無需驗資分鐘< =最大值):

public class Range<T> 
{ 
    public Range(T min, T max)   
    { 
     Min = min; 
     Max = max; 
    } 

    public T Min { get; private set; } 
    public T Max { get; private set; } 
} 

是BinaryProblemConfiguration後看起來就像這樣:

public class BinaryProblemConfiguration 
{ 
    public Range<int> XRange { get; set; } 
    public Range<int> YRange { get; set; } 
} 

你真正實施是製品廠。所以我中介不是很具描述性的名字吧:

public interface IProblemFactory 
{ 
    Problem CreateProblem(); 
} 

爲每種產品類型創建工廠。每個工廠都知道它創建什麼類型的產品以及它需要什麼類型的配置。 E.g:

public class BinaryProblemFactory : IProblemFactory 
{ 
    private BinaryProblemConfiguration _config; 
    private Random _random; 

    public BinaryProblemFactory(BinaryProblemConfiguration config) 
    { 
     _config = config; 
     // or you can use const seed here 
     _random = new Random(DateTime.Now.Millisecond); 
    } 

    public override Problem CreateProblem() 
    { 
     var x = GenerateValueInRange(_config.XRange); 
     var y = GenerateValueInRange(_config.YRange); 
     return new BinaryProblem(x, y); 
    } 

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

廠創建:

BinaryProblemConfiguration config = new BinaryProblemConfiguration(); 
config.XRange = new Range<int>(0, 100); 
config.YRange = new Range<int>(-50, 50); 

IProblemFactory problemFactory = new BinaryProblemFactory(config); 

通創建問題工廠某處爲IProblemFactory:

Problem problem = problemFactory.CreateProblem(); 

也有沒有特別需要的配置對象。我認爲產品的創造者應該知道如何創造產品。所以我寧願去與屬性XRange和YRange添加到工廠:

BinaryProblemFactory binaryProblemFactory = new BinaryProblemFactory(); 
binaryProblemFactory.XRange = new Range<int>(0, 100); 
binaryProblemFactory.YRange = new Range<int>(-50, 50); 
+0

是的,這就是我要的!工廠模式。只是一個愚蠢的懷疑,我真的需要我所有的工廠都實現Random屬性的同一個實例。如果將此接口轉換爲Random屬性的基類(抽象),是否有任何不便之處? – 2012-03-26 05:07:34

+0

當然,只需創建帶有受保護隨機字段的抽象ProductFactory即可。如果所有具體的工廠都需要它,您也可以將方法GenerateNewValueInRange移動到抽象工廠。 – 2012-03-26 05:42:07

+0

感謝您的建議。我已更新帖子並設置爲最終的當前設計。我想告訴你,因爲我覺得非常舒適..也許我沒有遵循指導原則,或者在我的IFactory和FactoryBase類中不能理解。你覺得怎麼樣? – 2012-03-27 19:16:52

0

如果我理解你的問題,我不太確定,但我會試着就此提出我的看法。希望能幫助到你。

我相信你選擇了錯誤的方法。 - 你有兩個類,但它們根本就不通信(儘管它們應該是) - 是的,你已經創建了抽象類來派生,但在這種情況下我沒有看到原因。他們沒有定義任何東西,他們不強制任何邏輯來派生類。當你創建一個接口時,你需要一個從它派生出來的人來實現它。你不能真正實現一個空的類/接口。

首先,我建議解決這個問題。創建需要特定方法或屬性的接口,以實現它們。這樣,您應該能夠更輕鬆地開發主應用程序,因爲您會知道,無論其他開發人員創建什麼問題,他都需要使用您可以使用的某些方法來實現您的界面。如果你允許實現一個空的界面,你不能確定,結果會是什麼,以及期待什麼。你不能依靠他們表現得很好(或者至少你不應該)。其次,不知道你是否知道它,但是當你使用模塊(Problem + Config作爲一個模塊)時,把它們放在一個單獨的.cs文件中。這樣,您可以擁有幾乎無限的數量,並且仍然能夠輕鬆維護您的應用。

第三,我會使用一些接口這樣的建議,這些類之間有一定的關係(通信):

public interface IProblem 
{ 
    IProblemConfiguration Config; 

    // other needed methods or properties 
}