使用对象类型在模块之间传递信息
本文关键字:之间 信息 模块 对象 类型 | 更新日期: 2023-09-27 18:32:04
我们有一个模块化的MVVM应用程序。其中一个界面如下所示
public interface ILogger
{
void ReportError(ErrorType type);
}
错误类型如下所示
class ErrorType
{
string Message;
string Title;
object Owner;
}
请注意类型对象。实现 ILogger 接口的模块只是从中调用 GetString(),因为它只需要调用模块的名称。对象的使用对我来说是一个问题。我们正在开发一个松散耦合的应用程序,我们允许任何对象在模块之间传递?
与可能导致拼写错误的字符串相比,使用justified为对象更灵活,并保证给出类型名称。此外,接口的实现器除了调用 GetString() 之外不做任何其他事情。
我请求一些建议。在我看来,对象的使用就像模块不知道如何识别它们之间。使用这样的对象是好的设计吗?
我在考虑更多
class ErrorType
{
string Message;
string Title;
string ModuleName;
}
如果您使用的只是对象的名称,那么我建议在创建 ErrorType 时使用反射来传递它,而不是存储整个对象。您的开发人员必须确保不使用硬编码值,因为如果您担心拼写错误/可维护性,这是允许的。
但是,如果出于任何其他原因需要该对象,则应保留它。否则,它只是不需要的开销。
不过,只有我的两分钱。
*这是一个SO问题,显示了如何获取当前方法,以及如何获取当前模块:
this.GetType().Module.Name;
既然string ModuleName
就是你现在所需要的,那就使用它吧。它将迫使您公开最少的信息,并且其他模块将无法作弊并尝试根据Owner
对象的类型做出任何决定。
实际代码中使用属性(最好在IErrorType接口上只读),因此很容易更改实现,即根据传入的对象计算ModuleName。
如果你试图捕获堆栈信息(如模块名称),你应该真正考虑使用 Log4Net 或 NLog - 无需重新发明轮子。
如果您的所有图层都在 .Net 中,我不明白使用 Object 类型会给您带来任何问题 - 它是其他所有内容的基类。 问题是您将如何处理这些信息(或其他人将做什么)? 它只有.到字符串,.等于,以及其他几种方法。您是否有推动日志记录设计的非功能性需求? 如果(尚)不需要"所有者",请不要包含它。
传递或不传递对象不一定会影响耦合;相反,它是一件事对另一件事的了解程度。 所以不要添加你不需要的东西。
实现 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()
更好,后者太隐式了,不会传达其意图或强制您的模块覆盖它。
当我们只需要模块名称时,模块名称是可以的,但事实并非如此,在另一种情况下,一个 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;}
}
等。
尽管这里的危险是你被创建越来越多的类冲昏头脑,没有人确定他们应该使用哪个类。