Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用对象类型在模块之间传递信息_C#_Design Patterns_Modularity - Fatal编程技术网

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

C# 使用对象类型在模块之间传递信息,c#,design-patterns,modularity,C#,Design Patterns,Modularity,我们有一个模块化的MVVM应用程序。其中一个接口如下所示 public interface ILogger { void ReportError(ErrorType type); } class ErrorType { string Message; string Title; object Owner; } ErrorType类型如下所示 public interface ILogger { void ReportError(ErrorType type);

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

public interface ILogger
{

    void ReportError(ErrorType type);
}
class ErrorType
{
  string Message;
  string Title;
  object Owner;
}
ErrorType类型如下所示

public interface ILogger
{

    void ReportError(ErrorType type);
}
class ErrorType
{
  string Message;
  string Title;
  object Owner;
}
注意类型对象。实现ILogger接口的模块只需从中调用GetString,因为它只需要调用模块的名称。在我看来,对象的使用似乎是个问题。我们正在开发一个松散耦合的应用程序,我们允许在模块之间传递任何对象

与可能导致打字错误的字符串相比,使用justified as object更灵活,并保证提供类型名称。此外,接口的执行器除了调用GetString之外不做任何事情

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

我想的更多的是

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

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

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

不过,只有我的两分钱

*下面是如何获取当前模块:

this.GetType().Module.Name;

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

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

不过,只有我的两分钱

*下面是如何获取当前模块:

this.GetType().Module.Name;
因为字符串ModuleName就是您现在所需要的全部,所以只需使用它即可。它将迫使您公开最少数量的信息,而其他模块将无法进行欺骗,并试图根据所有者对象的类型做出任何决定

在实际代码中,最好在IErrorType接口上使用只读属性,这样就可以很容易地更改实现,即根据传入的对象计算ModuleName。

因为字符串ModuleName就是您现在所需要的,所以只需使用它即可。它将迫使您公开最少数量的信息,而其他模块将无法进行欺骗,并试图根据所有者对象的类型做出任何决定


在实际代码中,最好在IErrorType接口上使用只读属性,这样就可以很容易地更改实现,即根据传入的对象计算ModuleName。

如果您试图捕获堆栈信息,如模块名称,您应该真正研究使用Log4Net或NLog-无需重新发明轮子

如果您的所有层都在.Net中,我看不出使用对象类型会给您带来什么问题-它是其他一切的基类。问题是你要做什么,或者其他人会如何处理这些信息?它只有.ToString、.Equals和几个其他方法。您是否有驱动日志设计的非功能性需求?如果还不需要所有者,就不要包含它


通过或不通过对象不一定会影响耦合;相反,这是一件事对另一件事的了解程度。因此,不要添加您不需要的内容。

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

如果您的所有层都在.Net中,我看不出使用对象类型会给您带来什么问题-它是其他一切的基类。问题是你要做什么,或者其他人会如何处理这些信息?它只有.ToString、.Equals和几个其他方法。您是否有驱动日志设计的非功能性需求?如果还不需要所有者,就不要包含它

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

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

次要说明:正确的方法名称是ToString

那么,对于ILogger需要什么,您有一个隐式接口。还不如将其显式化,并强制模块实现它:

interface INamed {
  string Name { get; }
}
然后注意我是如何将ErrorType重命名为Error的;其他名称如ErrorMessage也可以:

class Error {
  string Title;
  string Message;
  INamed NamedModule;
}
但当然,拥有这样一个简单的接口,仅仅为了得到一个名字,可能有点过头了;您可以在提议时使用字符串:

class Error {
  string Title;
  string Message;
  string ModuleName;
}
这两种方法都比使用Object.ToString要好,后者太含蓄,无法传达其意图或强制力 我们的模块可以覆盖它

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

次要说明:正确的方法名称是ToString

那么,对于ILogger需要什么,您有一个隐式接口。还不如将其显式化,并强制模块实现它:

interface INamed {
  string Name { get; }
}
然后注意我是如何将ErrorType重命名为Error的;其他名称如ErrorMessage也可以:

class Error {
  string Title;
  string Message;
  INamed NamedModule;
}
但当然,拥有这样一个简单的接口,仅仅为了得到一个名字,可能有点过头了;您可以在提议时使用字符串:

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

任何一种方法都比使用Object.ToString好,Object.ToString过于隐式,无法传达其意图或强制模块覆盖它。

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

我不确定它是否只是一个简单的所有者或模块名,但我确实欣赏使用object.tostring的隐式本质

尽管我有过这样一个想法,但实际上是使用所有者对象的接口来识别调用方,比如IDocument,它将URL和文本作为可能的值,然后日志服务的客户端将检查所有者是否属于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;}
}
等等


尽管这里的危险在于,创建越来越多的类会让你心神不宁,而且没有人知道它们应该使用哪个类。

当我们只需要模块名时,模块名是可以的,但事实并非如此,在不同的情况下,url应该作为标识符,还有一个url和模块名,我们在这里做什么

我不确定它是否只是一个简单的所有者或模块名,但我确实欣赏使用object.tostring的隐式本质

尽管我有过这样一个想法,但实际上是使用所有者对象的接口来识别调用方,比如IDocument,它将URL和文本作为可能的值,然后日志服务的客户端将检查所有者是否属于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;}
}
等等


尽管这里的危险在于,创建越来越多的类会让您忘乎所以,而且没有人知道它们应该使用哪个类。

注意,我们关心的是模块之间使用的接口。传递对象的问题在于,模块需要从另一个模块得到什么并不明显;如果是这样的话,我会使用ModuleName Suggestion注意,我们关心的是模块之间使用的接口。传递对象的问题在于,模块需要从另一个模块得到什么并不明显;如果是这样,我会使用ModuleNamesuggestion@Jimmy没问题,随时乐意帮忙!和往常一样,如果这是你一直在寻找的东西,请勾选接受:@Jimmy没问题,随时乐意帮助!与往常一样,如果这是您一直在寻找的,请选中一个要接受的复选标记:模块之间需要什么信息很重要,如果有新的数据结构或接口是有意义的,则可以这样做。仅仅传递一个对象弊大于利。但是我可以让您回到您设置的注释中作为答案,这说明模块名称应该是基于传入对象的只读属性。。。因此,这意味着对象被赋予错误类,并通过接口以字符串-模块名的形式公开……模块之间需要什么信息很重要,如果有新的数据结构或接口是有意义的,那么就可以这样做。仅仅传递一个对象弊大于利。但是我可以让您回到您设置的注释中作为答案,这说明模块名称应该是基于传入对象的只读属性。。。因此,这意味着对象被赋予了错误类,并通过接口作为字符串模块名公开。。。