2012-04-11 36 views
3

我有几个不同的对象,但我必须对它们做类似的操作。 什么是更好的使用: 1.几种方法和使用这些对象作为类型参数。 2.使用一个获取System.Object作为参数的方法。在这个方法里面,我将检查参数的类型并做一些操作。哪个代码更好的编程风格

例如,我应该发送一些操作的通知。我有对象Action1,Action2,Action3 ... ActionN,其中包含这些操作的详细信息。我应该使用:

public void SendNotificationForAction1(Action1 action) {} 
    public void SendNotificationForAction2(Action2 action) {} 
    public void SendNotificationForActionN(ActionN action) {} 

public void SendNotification(Object action) 
    { 
     //here I will check type of action and do something 
    } 
+2

答案是,这取决于。 – 2012-04-11 11:36:22

+0

绝对是第一个......但是没有什么能够阻止你将它们结合起来 – scibuff 2012-04-11 11:36:42

+0

@scibuff,怎么样?我认为编译时绑定将在第一种方法中完成 – Habib 2012-04-11 11:37:42

回答

8

第一个是类型安全的,第二个是没有的。因此,如果我选择这两个选项,我会选择第一个。

另一方面,是否有可能采用完全不同的方法? 如果您有一个基类或接口Action,其他类从哪里派生? 接口或基类可能有一个'GetDetailsForNotification'方法,您可以在执行器中实现该方法,并且您可以在SendNotificationForAction方法中使用该方法。

这样的事情,但是,offcourse,我不知道这是不是在你的情况下可行:

interface IAction 
{ 
    string GetDetailsForNotification(); 
} 

public class Action : IAction{ 
    public string GetDetailsForNotification() 
    { 
     return "details from Action"; 
    } 
} 

public class Action2 : IAction{ 
    public string GetDetailsForNotification() 
    { 
     return "details from Action2"; 
    } 
} 


public void SendNotificationForAction(IAction action) { 

    var details = action.GetDetailsForNotification(); 
    ... 
} 
+0

打败我吧。只有建议将SendNotificationForAction1的参数更改为IAction,而不是Action,以使其更通用一些。 – Joshua 2012-04-11 11:46:09

0

我会去与第一种方法。

它需要创建更多的方法,并可能更多的代码,但我相信它更容易使用和类型安全。

您的第二种方法不允许我在编译时知道该方法在不读取代码的情况下期望的对象类型(假设您将这些代码分发为库),并且如果我传递了错误的方法,你唯一能做的就是让它在运行时失败 - 不是很好。

8

我猜这取决于:

是否发送通知的代码差不多相同?然后,我会选择:

public void SendNotificationFor<T>(T action) {} 

,否则我可能会选择overload方法:

public void SendNotification(Action1 action) {} 
public void SendNotification(Action2 action) {} 
public void SendNotification(ActionN action) {} 
+0

也许这不是最好的例子。发送通知的代码是不同的,取决于Action的类型。所以在我的情况下重载方法会更好。 – Tannheuser 2012-04-11 11:49:37

+0

@Tannheuser在这种情况下更难的是做一个通用的方法。这听起来像方法超载将是一个完美的匹配!重载的方法不需要共享名称以外的任何其他内容。 – 2012-04-11 11:56:04

0

你应该尽量保持方法尽可能地通用。

SendNotification方法可以建立这样的:

public void SendNotification<T>(T action) where T : SpecialAction { 
} 

类/接口SpecialAction就可以拥有属于行动之间的不同方法。例如:

[abstract class] [interface] SpecialAction { 
    public string GetName(); 
    public bool CanDoX(); 
} 
2

Strategy Pattern可能适合在这里太:

private interface INotificationStrategy<T> // or non-generic with object 
{ 
    void SendNotification(T action); 
} 

public class StringNotificationStrategy : INotificationStrategy<string> 
{ 
    public void SendNotification(string action) 
    { 
     throw new NotImplementedException(); 
    } 
} 

工厂可以为您提供正确的执行,你可以提供进一步实现在不破坏现有的接口...

0

正如大家所说,这取决于,但通常我更喜欢第二种方法的变体(下面),因为未来可以更容易地扩展(当然,如果需要的话)。

interface ISendNotificationHandler 
{ 
    Type ActionType { get; } 
    void SendNotification(object action) 
} 


class Action1SendNotificationHandler : ISendNotificationHandler 
{ 
    public Type ActionType {get{return typeof(Action1);}} 
    public void SendNotification(object action) 
    { 
     Action1 a = (Action1)action; 
     // TODO: send notification 
    } 
} 

// your method originally posted 
public void SendNotification(Object action)  
{ 
     var handlers = new ISendNotificationHandler[]{ new Action1SendNotificationHandler(), /* etc*/} 

     // 
     var handler = handlers.FirstOrDefault(h=>action.GetType().IsSubclassOf(h.ActionType)) 
     if(handler != null) 
     { 
      handler.SendNotification(action); 
     } 
     else 
     { 
      throw new Exception("Handler not found for action " + action); 
     } 
} 
+0

阿列克谢,这就是我问这个问题的原因。未来有可能需要扩展。而且我认为在这种情况下,二线队更好。 – Tannheuser 2012-04-11 12:00:28

+0

'有可能在未来必须扩展 - 然后我也投票支持2 -nd – 2012-04-11 13:37:43

0

你有没有使用Observer模式

Wiki Link是这里考虑。

为了简化,可以说你已经订阅了报纸,当过有报纸的新版本(事件),用户将得到通知,并且新版本的交付。

0

这里是我的尝试:

每ActionN类是从基本动作衍生:

class Action1: Action, INotify 
{ 
    public void override SendNotification() {...} 
} 

如果一些通知,有共同的实现,那么有它在Action类。

现在谁发送通知的类做到这一点:

class Sender 
{ 
    public void SendNotif(INotify actn) 
    { 
     actn.SendNotification(); 
    } 

} 

,并发送正确的对象SendNotif()方法。