事件,代表或接口?

时间:2009-08-19 13:25:54

标签: c#

假设我有一个 Monkey 类,有时需要获取 Banana 的实例。提供香蕉的方式对猴子不感兴趣,但它确实启动了香蕉的采集。

现在我至少有三种方法可以将我的猴子送到香蕉供应商那里。 最好的方法是什么?

1。事件

举起Monkey.BananaNeeded事件。事件处理程序设置BananaNeededEventArgs.Banana属性。

2。接口

调用IBananaProvider.GetBananaIBananaProvider实例作为构造函数参数或通过属性注入到猴子中。

第3。代表

调用System.Func<Banana>类型的委托。委托作为构造函数参数或通过属性注入猴子。这个很诱人,因为它不需要声明任何额外的接口或类,但显然它不是一个受欢迎的选择。

7 个答案:

答案 0 :(得分:7)

我不喜欢事件和委托选项,除非有一种机制可以确保不会附加多个处理程序。因此,选项2是IMO的赢家。

答案 1 :(得分:4)

如果有几个可能的香蕉供应商,事件模型效果最好,即猴子依次要求所有供应商提供香蕉,而第一个可以提供香蕉的供应商可以提供它。

另外两个型号适用于每只猴子的单个香蕉证明器。委托更容易为其创建提供程序,并且界面更加结构化。

答案 2 :(得分:1)

上述场景中最好的方法是使用Interface。在OOAD术语中,我们可以定义上面的场景,因为Monkey类有一个香蕉。

答案 3 :(得分:1)

我通常使用2。

IBananaProvider bananaProvider = ProviderFactory.Get<IBananaProvider>();

答案 4 :(得分:1)

Monkey上有一些操作需要香蕉。

猴子需要获得香蕉才能进行这些操作。你一定可以把Banana作为操作的参数。

我将删除Money对IBananaProvider的依赖。

class Monkey
{
   void FeedWith(Banana banana) { ... }
}

调用者的责任是获取香蕉,而不是猴子。

我在这里提倡在实体中注入服务。

答案 5 :(得分:1)

理想情况下,依赖注入是更普遍接受的方法。

另一种尝试方法是消息队列

在这种情况下,Monkey基本上可以将消息“发布”到某个队列中,以获得美味的香蕉。这个“发布”将触发正在监视队列的某些提供者,然后完成请求 - 提供者的实际实例响应无关紧要。 Monkey然后等待对原始邮件的回复,并在感兴趣的包裹从BananaProvider到达时采取措施。

消息队列将提供者和使用者分离。当然,仍有某种形式的合同“到位,但在请求的另一端并且答案是无关紧要的。

答案 6 :(得分:1)

我同意并说选项2是最好的解决方案。代表通常意图是,委托某些东西,换句话说做某事,而事件意味着立即响应发生的事情,通常与用户有关。界面简单地说,“这就在这里,你可以做到。”因为您不希望香蕉或猴子一开始做任何事情,并且您不希望用户直接与代码的内部工作进行交互,所以界面会赢得它。你所需要的只是知道猴子可以接受香蕉。他之后决定用那些香蕉做的事取决于他,香蕉本身以及周围的代码不应该关注它。