代码之家  ›  专栏  ›  技术社区  ›  Matt Warren

有用的迷你模式(不是设计模式)

  •  2
  • Matt Warren  · 技术社区  · 16 年前

    我最常用的迷你图案是:

    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" }
                                 };
    

    这意味着,我可以将单击的按钮与ArrayList中的每个项目进行比较,而不是使用带有每个按钮大小写的switch语句。然后,当我找到匹配项时,我启动正确的文件(尽管第二部分“查找”的操作可能是委托或其他任何操作)。

    主要的好处是,我没有记住为每个switch语句添加所有正确代码的问题,我只是向lookup 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();            
    
    9 回复  |  直到 16 年前
        1
  •  5
  •   Jimmy    16 年前

    请omg使用此版本。

    VideoLookup = new Dictionary<Button, string> {
        { buttonVideo1, "Video01.flv" },
        { buttonVideo2, "Video02.flv" },
        { buttonVideo3, "Video03.flv" }, 
        { buttonVideo4, "Video04.flv" },
        { buttonVideo4, "Video04.flv" }
    };
    
        2
  •  3
  •   BobbyShaftoe    16 年前

        3
  •  3
  •   Tim Frey    16 年前

    关于开关,我写了很多这样的东西:

    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%的时间都不重要。

        4
  •  3
  •   Rich Apodaca    16 年前

    在Java中,我有时发现实现公共接口的私有内部类对于由紧密耦合元素组成的对象非常有用。我看到过在使用Allen Holub的创建UI的上下文中讨论的这个小模式(习惯用法) Visual Proxy 建筑,但仅此而已。据我所知,它没有名字。

    例如,假设您有一个可以提供迭代器的集合接口:

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

    如果您有一个实现集合的堆栈,则可以将其迭代器实现为私有内部类:

    public class Stack implements Collection
    {
      ...
    
      public Iterator iterate()
      {
        return new IteratorImpl();
      }
    
      private class IteratorImpl implements Iterator
      {
        public boolean hasNext() { ... }
        public Object next() { ... }
      }
    }
    

    堆栈及其迭代器将趋向于紧密耦合。最坏的情况是,将堆栈的迭代器实现为公共类可能会迫使您破坏堆栈的封装。私有内部类允许您避免这种情况。无论哪种方式,都可以避免用一些真正的实现细节来污染类层次结构。

        5
  •  2
  •   philsquared    16 年前

    在我的上一份工作中,我写了一个C++版本的Andrei Alexandrescu和Petru Marginean在C++中引入的概念。 original article here ).

    这真的很酷,因为它可以让您在不中断流程的情况下将错误处理或条件检入与正常代码交织在一起-例如:

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

    这将检查第一个参数是否为null,如果为null,则抛出EnforcementException并将第二个参数作为消息,否则返回第一个参数。还有一些重载也采用字符串格式参数,还有一些重载允许您指定不同的异常类型。

    你可能会争辩说,这类事情在C#中不太相关,因为运行时检查更好,而且已经非常有用了——但是这个习惯用法让你更接近源代码,提供更多信息,同时保持表达能力。

    我可能会编写一个开源版本并从这里链接它。

        6
  •  1
  •   Jimmy    16 年前

    因为当我快速编写代码(截止日期!截止日期!为什么我在stackoverflow.com上?截止日期!)时,我会得到这样的代码:

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

        7
  •  0
  •   Jeff Kotula    16 年前

    对于Windows窗体,我经常使用Tag字段来放置psuedo命令字符串,这样就可以为一组共享的按钮提供一个事件处理程序。这对于功能几乎相同但参数化的按钮尤其有效。

    对于具有某种形式的用于调度操作的基于文本的命令处理器的应用程序,标记是一个刚刚输入命令处理器的字符串。很好用。

        9
  •  0
  •   supercat    14 年前

    也许已经有了更好的方法(vbEx2005/.Net2.0),但我发现有一类泛型委托创建者非常有用,它接受一个方法,该方法接受一些参数,以及这些参数中的所有或除一个以外的所有参数的值,并生成一个委托,该委托在调用时,将使用指定的参数调用指定的函数。与ParameteredThreadStart等基于ParamArray的东西不同,所有东西都是类型安全的。

    例如,如果我说:

    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”)。不幸的是,对于我想要支持的每一个不同数量的参数,我最终不得不有单独的泛型类和方法,但是将所有的剪切和粘贴放在一个文件中要比将额外的代码分散在各处以创建适当的委托更好。