1

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

public interface ILogger
{

    void ReportError(ErrorType type);
}

ErrorType 类型如下所示

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

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

与可能导致拼写错误的字符串相比,justified as object 的使用更加灵活并保证提供类型名称。除了调用 GetString() 之外,接口的实现者也没有做任何事情。

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

我想更多的是

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

5 回答 5

2

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

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

不过,只是我的两分钱。

*这是一个 SO 问题,显示如何获取当前方法,这里是如何获取当前模块:

this.GetType().Module.Name;
于 2012-04-23T18:01:23.320 回答
1

因为string ModuleName这就是您现在所需要的,只需使用它即可。它将迫使您公开最少数量的信息,其他模块将无法作弊并尝试根据Owner对象类型做出任何决定。

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

于 2012-04-23T18:02:21.170 回答
1

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

如果您的所有图层都在 .Net 中,我看不出使用 Object 类型会给您带来任何问题——它是其他所有内容的基类。问题是您将如何处理(或其他人将如何处理)这些信息?它只有 .ToString、.Equals 和其他几个方法。您是否有驱动日志设计的非功能性需求?如果(还)不需要“所有者”,请不要包含它。

传递或不传递对象不一定会影响耦合;相反,它是一件事对另一件事的了解程度。所以不要添加你不需要的东西。

于 2012-04-23T18:13:07.777 回答
1

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

(小注:正确的方法名称是ToString()

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

interface INamed {
  string Name { get; }
}

然后(注意我如何重命名ErrorTypeError;其他名称ErrorMessage也可以):

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

但是当然,拥有这么简单的界面,只是为了获得一个名字,可能有点过头了。你可以string按照你的提议使用:

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

无论哪种方式都比 using 更好Object.ToString(),后者过于隐含并且不会传达其意图或强制您的模块覆盖它。

于 2012-04-23T20:06:23.140 回答
0

当我们只需要模块名称时,模块名称就可以了,但事实并非如此,在另一种情况下,需要一个 url 作为标识符,而另一种情况是 url 和模块名称,那么我们在这里做什么呢?

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

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

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

也许类继承可以提供帮助。

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

等等

尽管这里的危险是你会因创建越来越多的类而忘乎所以,没有人知道他们应该使用哪个类。

于 2012-04-24T09:42:19.307 回答