簡體   English   中英

有用的迷你圖案(不是設計圖案)

[英]Useful mini patterns (not design patterns)

我最常用的迷你圖案是:

VideoLookup = new ArrayList  { new ArrayList { buttonVideo1, "Video01.flv" },
                               new ArrayList { buttonVideo2, "Video02.flv" },
                               new ArrayList { buttonVideo3, "Video03.flv" }, 
                               new ArrayList { buttonVideo4, "Video04.flv" },
                               new ArrayList { buttonVideo4, "Video04.flv" }
                             };

這意味着,不是每個按鈕都有一個case的switch語句,而是只需將單擊的按鈕與ArrayList中的每個項目進行比較。 然后,當我找到匹配時,我啟動了正確的文件(盡管第二部分“查找”的操作可能是委托或其他任何事情)。

主要的好處是我沒有記住為每個switch語句添加所有正確代碼的問題,我只是在查找ArrayList中添加一個新項。

(是的,我知道使用ArrayList不是最好的方法,但它是舊的代碼。而且我知道每次循環遍歷數組不如使用switch語句那么高效,但是此代碼不在緊環)

是否有其他人使用任何迷你圖案可以節省時間/精力或使代碼更具可讀性? 它們不必僅與GUI相關

更新:不要復制這段代碼,我知道這很糟糕,但我沒有意識到有多糟糕。 請改用這樣的東西。

Hashtable PlayerLookup = new Hashtable();
PlayerLookup.Add(buttonVideo1, "Video01.flv");
PlayerLookup.Add(buttonVideo2, "Video02.flv");
PlayerLookup.Add(buttonVideo3, "Video03.flv");
PlayerLookup.Add(buttonVideo4, "Video04.flv");

string fileName = PlayerLookup[currentButton].ToString();            

請請使用此版本。

VideoLookup = new Dictionary<Button, string> {
    { buttonVideo1, "Video01.flv" },
    { buttonVideo2, "Video02.flv" },
    { buttonVideo3, "Video03.flv" }, 
    { buttonVideo4, "Video04.flv" },
    { buttonVideo4, "Video04.flv" }
};

您可以創建一個結構或對象,該結構或對象具有按鈕引用和表示文件名的字符串,然后是這些事物的列表。 或者,你可以使用一個詞典,讓自己更容易。 有很多方法可以改進。 :)

關於開關的主題,我寫了很多這樣的東西:

public Object createSomething(String param)
{
    return s == null                          ? new NullObject() :
           s.equals("foo")                    ? new Foo() :
           s.equals("bar")                    ? new Bar() :
           s.equals("baz") || s.equals("car") ? new BazCar() :
                                                new Object();
}

我認為與常規switch語句相比,它看起來更具可讀性,並且能夠進行更復雜的比較。 是的,它會慢一點,因為你需要比較每個條件,但99%的時間無關緊要。

在Java中,我有時會發現實現公共接口的私有內部類對於由緊耦合元素組成的對象非常有用。 我已經看到了在使用Allen Holub的Visual Proxy架構創建UI的背景下討論的這種迷你模式(成語),但除此之外沒有多少。 據我所知,它沒有名字。

例如,假設您有一個可以提供迭代器的Collection接口:

public interface Collection
{
  ...

  public Iterator iterate();
}

public interface Iterator
{
  public boolean hasNext();
  public Object next();
}

如果你有一個實現Collection的Stack,那么你可以將它的Iterator實現為私有內部類:

public class Stack implements Collection
{
  ...

  public Iterator iterate()
  {
    return new IteratorImpl();
  }

  private class IteratorImpl implements Iterator
  {
    public boolean hasNext() { ... }
    public Object next() { ... }
  }
}

Stack.IteratorImpl可以完全訪問Stack的所有私有方法和字段。 同時,除了Stack之外,Stack.IteratorImpl對所有人都是不可見的。

堆棧及其迭代器將傾向於緊密耦合。 最糟糕的情況是,將Stack的Iterator實現為公共類可能會迫使您破壞Stack的封裝。 私有內部類可以讓你避免這種情況。 無論哪種方式,您都可以避免使用真正的實現細節來污染類層次結構。

在我上一份工作中,我編寫了由Andrei Alexandrescu和Petru Marginean在C ++中引入的Enforcements概念的C#版本( 原文在這里 )。

這真的很酷,因為它允許您使用普通代碼交錯錯誤處理或條件檢查而不會破壞流程 - 例如:


string text = Enforce.NotNull( myObj.SomeMethodThatGetsAString(), "method returned NULL" );

這將檢查第一個參數是否為null,如果是,則拋出帶有第二個參數的EnforcementException作為消息,否則返回第一個參數。 還有重載采用字符串格式化參數,以及允許您指定不同異常類型的重載。

您可能會認為這種事情在C#中不太相關,因為運行時檢查更好並且已經非常有用 - 但是這個習慣用法可以讓您更接近源並提供更多信息,同時保持表達。

我使用相同的系統進行前后條件檢查。

我可能會寫一個開源版本並從這里鏈接它。

因為當我快速編寫代碼時(最后期限!截止日期!為什么我在stackoverflow.com上?截止日期!),我最后得到了這樣的代碼:

Button1.Click += (o,e) => { DoSomething(foo); };

這會在某些時候導致我的內存泄漏嗎? 我不確定! 這可能值得一個問題。 確認! 截止日期!

也許已經有了更好的方法(vbEx2005 / .Net2.0),但我發現有一類通用委托創建者接受一個帶有一些參數的方法,以及所有參數的值都很有用。 ,或者除了一個參數之外的所有參數,並產生一個委托,當被調用時,它將使用指示的參數調用指定的函數。 與基於ParamArray的東西(如ParameterizedThreadStart)不同,一切都是類型安全的。

例如,如果我說:

Sub Foo(param1 As Integer, param2 As String)
    ...
End Sub

...
  Dim theAct as Action(of Integer) = _
      ActionOf(of Integer).NewInv(AddressOf Foo,"Hello there")

  theAct(5)
...

結果將是在聲明Foo的對象上調用Foo(5,“Hello there”)。 不幸的是,我最終必須為我想要支持的每個不同數量的參數設置單獨的泛型類和方法,但是將所有剪切和粘貼放在一個文件中比在每個地方散布額外的代碼以創建適當的代表。

對於Windows窗體,我經常使用Tag字段來放置一個偽命令字符串,這樣我就可以為一組共享按鈕設置一個事件處理程序。 這對於完全相同但參數化的按鈕特別有效。

在第一個示例中,我將按鈕的Tag設置為等於視頻文件的名稱 - 不需要查找。

對於具有某種形式的基於文本的命令處理器用於調度操作的應用程序,Tag是一個剛剛送入命令處理器的字符串。 工作得很好。

(順便說一句:我看過用於迷你圖案的“成語”一詞......)

我在C#中開始看到的一個新習慣用法是使用閉包參數來封裝該方法需要運行的一些配置或設置。 這樣,您就可以控制代碼必須在方法中運行的相對順序。

這被稱為Martin Fowler的嵌套閉包: http//www.martinfowler.com/dslwip/NestedClosure.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM