使用对象类型在模块之间传递信息

时间:2012-04-23 17:51:17

标签: c# design-patterns modularity

我们有一个模块化MVVM应用程序。其中一个界面如下所示

public interface ILogger
{

    void ReportError(ErrorType type);
}

ErrorType类型如下所示

class ErrorType
{
  string Message;
  string Title;
  object Owner;
}

请注意对象类型。实现ILogger接口的模块只需要调用GetString(),因为它只需要调用模块的名称。对象的使用看起来像是一个问题。我们正在开发一个松散耦合的应用程序,我们让任何对象在模块之间传递?

对齐的对象的使用更灵活,并且保证与字符串相比给出类型名称,这可能导致拼写错误。除了调用GetString()之外,接口的实现者还没有做任何事情。

我要求一些建议。对象的使用在我看来就像模块不知道如何识别它们之间。像这样使用对象是好的设计吗?

我在考虑更多

 class ErrorType
 {
      string Message;
      string Title;
      string ModuleName;
 }

5 个答案:

答案 0 :(得分:2)

如果您使用的只是对象的名称,那么我建议在创建ErrorType时使用反射来传递它,而不是存储整个对象。您的开发人员必须确保不使用硬编码值,因为如果您担心拼写错误/可维护性,那将是允许的。*

但是,如果您因任何其他原因需要该对象,那么您应该保留它。否则,它只是不需要的开销。

虽然只是我的两分钱。

* Here is a SO question that shows how to get Current Method以下是获取当前模块的方法:

this.GetType().Module.Name;

答案 1 :(得分:1)

由于string ModuleName就是您现在所需要的,所以只需使用它即可。它将强制您公开最小量的信息,而其他模块将无法作弊并尝试根据Owner对象的类型做出任何决定。

在实际代码中使用属性(最好只在IErrorType接口上读取),因此很容易更改实现,即根据传入的对象计算ModuleName。

答案 2 :(得分:1)

如果您正在尝试捕获堆栈信息(如模块名称),您应该真正考虑使用Log4Net或NLog - 无需重新发明轮子。

如果所有图层都在.Net中,我不会看到使用Object类型会导致任何问题 - 它是其他所有内容的基类。问题是你要做什么(或其他人会做什么)的信息?它只有.ToString,.Equals和其他一些方法。您是否有驱动日志设计的非功能性需求?如果(还)不需要“所有者”,则不要包含它。

传递或不传递物体不一定会影响耦合;相反,它是多少一件事知道另一件事。所以不要添加你不需要的东西。

答案 3 :(得分:1)

  

实现ILogger接口的模块只需要调用GetString(),因为它只需要调用模块的名称

(次要说明:正确的方法名称为ToString()

那么,你有一个隐式接口,关于ILogger 需要什么。不妨让它显式,并强制模块实现它:

interface INamed {
  string Name { get; }
}

然后(请注意我如何将ErrorType重命名为Error;其他名称如ErrorMessage也可以。)

class Error {
  string Title;
  string Message;
  INamed NamedModule;
}

但是,当然,拥有这样一个简单的界面,只是为了获得一个名字,可能会有点过分;您可以在提议时使用string

class Error {
  string Title;
  string Message;
  string ModuleName;
}

无论哪种方式都比使用Object.ToString()更好,因为{{1}}过于隐含,无法传达其意图或强制模块覆盖它。

答案 4 :(得分:0)

当我们需要的只是模块名称时,模块名称是可以的,但事实并非如此,有一种不同的情况,其中url是标识符,另一个是url和模块名称,所以我们该怎么做这里吗?

我不确定它只是一个简单的所有者或模块名称,但是我很欣赏使用object.tostring的隐含性。

虽然我有一个实际上是使用所有者对象的接口来识别调用者,例如IDocument,它将URL和Text作为可能值,然后日志服务的客户端将检查所有者是否属于类型IDocument,并能够用它做更多。

肯定需要添加有关调用类的更多信息,而不仅仅是模块名称,有时它甚至不需要。

也许一个班级heirachy可以提供帮助。

Class Message
{
   string Title {get; set;}
   string Message {get; set;}
}

Class ModuleMessage: Message
{
   string ModuleName  {get; set;}
}

Class URLMessage: Message
{
   string URL {get; set;}
}

Class DocumentMessage: URLMessage
{
   string Text  {get; set;}
}

虽然这里存在的危险是你不得不创造越来越多的课程而且没有人能确定他们应该使用哪个课程。