C# 使用对象类型在模块之间传递信息
我们有一个模块化的MVVM应用程序。其中一个接口如下所示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);
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没问题,随时乐意帮助!与往常一样,如果这是您一直在寻找的,请选中一个要接受的复选标记:模块之间需要什么信息很重要,如果有新的数据结构或接口是有意义的,则可以这样做。仅仅传递一个对象弊大于利。但是我可以让您回到您设置的注释中作为答案,这说明模块名称应该是基于传入对象的只读属性。。。因此,这意味着对象被赋予错误类,并通过接口以字符串-模块名的形式公开……模块之间需要什么信息很重要,如果有新的数据结构或接口是有意义的,那么就可以这样做。仅仅传递一个对象弊大于利。但是我可以让您回到您设置的注释中作为答案,这说明模块名称应该是基于传入对象的只读属性。。。因此,这意味着对象被赋予了错误类,并通过接口作为字符串模块名公开。。。