2012-11-27 56 views
4

在工作中,我正在執行此應用程序,它從外部文件(Excel工作表,文本文件...)獲取值,並將這些值轉換爲複雜的指令,並將其傳送到另一個系統。如何減少此代碼中的耦合

下面的代碼是有點簡化(沒有指令和非常簡單的邏輯),但這個想法保持不變。我有大約60個不同的翻譯人員,他們運行着各種不同的業務邏輯。有些只需要一個參數就可以運行。其他人則有多個論點。

我有一個抽象翻譯類。該類的用戶將使用2個公共方法:翻譯運行翻譯邏輯,CanTranslate允許查看翻譯器是否準備好開始。

使用此抽象類的開發人員需要實現將包含實際業務邏輯的DoTranslate方法。默認情況下,CanTranslate總是返回true,但如果需要驗證,它可以被覆蓋。

這裏的抽象譯者基類:

// Contains some base logic which is the same for all translators 
public abstract class BaseTranslator 
{ 
    // Public translate method 
    public void Translate() 
    { 
     if (CanTranslate()) 
      DoTranslate(); 
    } 

    // Checks if we are ready to translate 
    // True by default 
    public virtual bool CanTranslate() 
    { 
     return true; 
    } 

    // This method is used to implement business logic 
    public abstract void DoTranslate(); 
} 

而且這裏有一個具體的翻譯類的實現:

// Translates beer names 
public class ReverseTranslator : BaseTranslator 
{ 
    // Use of properties to allow strongly typed arguments 
    // which can be seen by the developer at design time 
    public string BeerName { get; set; } 

    // Validation 
    public override bool CanTranslate() 
    { 
     if (BeerName.Equals("Budweiser") || BeerName.Equals("Stella")) 
      return true; 
     else 
      return false; 
    } 

    // Implementation of the business logic 
    public override void DoTranslate() 
    { 
     char[] letters = BeerName.ToCharArray(); 
     Array.Reverse(letters); 
     Console.WriteLine(new string(letters)); 
    } 
} 

這裏是它看起來像在使用時:

class Program 
{ 
    public static void Main(string[] args) 
    { 
     var translator = new ReverseTranslator(); 

     translator.BeerName = "Stella"; 
     translator.Translate(); 

     translator.BeerName = "I'm not a beer"; 
     // This line will not translate since it's not a valid beer name. 
     translator.Translate(); 

     Console.ReadLine(); 
    } 
} 

Pro's:

  • 在小維護單元
  • 翻譯很容易在應用
  • 翻譯人員可以很容易地進行單元測試
  • 屬性允許翻譯的用戶看見哪個參數是的其它部分重用分離特定的業務邏輯需要

我的問題:

  • 不同的控制器CLASSE s正在使用許多翻譯。我有太多的耦合。

我想過使用工廠模式創建翻譯器,但後來我不能在設計時使用屬性作爲參數提示。

所以我基本上尋找一個解決方案,在設計時你可以很容易地看到哪些參數是必需的。同時我希望通過不讓每個控制器擁有30個新的xTranslator語句來減少耦合。

PS:我被限制爲使用.NET 3.5代碼。

+0

你如何確定哪一個翻譯器用於行? 你只是創建每種類型的翻譯器之一,並測試它是否CanTranslate? –

回答

0

爲一個具體的類的具體參數的設計時信息:你需要用具體類的實例來工作。
要減少控制器中的耦合:您需要限制抽象類的實例。
你不能同時在同一個地方。

重新設計您的整體設計可以消除耦合並消除對設計時間信息的需求。

將翻譯器的創建和初始化移出控制器到工廠或IoC容器中,該容器將外部文件中的一行數據作爲輸入(如果需要,可將其按需處理爲可使用的格式)。

翻譯人員是否需要一個構造函數來獲取參數集合。
優點:

  • 只有本身需要了解自身或 其參數的詳細信息,具體類。
  • 工廠大概需要在哪些情況下要使用的翻譯信息。

class TranslatorFactory 
{ 
    //translator lookup table 
    private Dictionary<string, Func<List<string>,BaseTranslator>> Translators = 
     new Dictionary<string,Func<List<string>,BaseTranslator>>{ 
      {"Reverse", (args)=>new ReverseTranslator(args)}, 
      {"Explode", (args)=>new ExplodeTranslator(args)}  }; 

    public BaseTranslator GetTranslatorForRow(string command, List<string> arguments) 
    { 
     if(Translators.ContainsKey(command)) 
     { 
      return Translators[command](arguments); 
     } 
     return null; //or default, or throw exception 
    } 
} 


abstract class BaseTranslator 
{ 
    ... 
    public BaseTranslator(List<string> args) 
    { 
    } 
} 

class ReverseTranslator: BaseTranslator 
{ 
    public string BeerName {get;set;} 
    public ReverseTranslator(List<string> args) 
    { 
     BeerName = args[0]; 
    } 
} 

您可以進一步使用屬性和反射去除工廠和具體類之間的耦合,以動態構建查找表。

[TranslatorFor("Reverse")] 
class ReverseTranslator: BaseTranslator 
{ 
    ... 
} 
2
different controller classes are using many translators. I have too much coupling 

控制器類應該只取決於抽象,它是BaseTranslator。因此,你不會有太多的耦合,確實會是耦合代碼鬆散。通過依賴注入(例如通過構造函數參數)將依賴注入到控制器中。

的一個選項,以使你的代碼只依賴於基本類型 - 在基類中創建字符串屬性Text

BaseTranslator translator = new ReverseTranslator(); // inject implementation 
translator.Text = "Stella"; 
translator.Translate(); 
translator.Text = "I'm not a beer"; 
translator.Translate(); 
+0

添加有關如何處理不同類型的輸入的說明(因爲他們期望不同的參數),這將是答案。 – Tengiz

0

它發生,我認爲有一些矛盾有關:

  • 在一個一旁的翻譯作者可以定義自己的具體類(並補充說,必須有一個值的具體類的正常工作新的「強制性」屬性)
  • 在你依賴於新的另一面在你的代碼中由其他人定義的具體類,因爲你是一個實例化類並將正確參數傳遞給它們的實例

如果這是正確的,我相信你沒有找到適合你的模型的抽象級別。換句話說,你目前的抽象對你(或多或少)都沒有幫助,因爲它在每個具體類中都有所擴展。所以我的建議是首先看模型本身(但這只是一個猜測,因爲我不知道你的模型:-))。

有人在這裏很可能將能夠更好地指導你,如果你在那裏能夠提供的名單說,7-10代表具體的類名和他們期望,讓我們瞭解您的域更好的輸入值。

+0

這是一個評論,然後是答案。 –