我正在尝试尽可能多地遵循SOLID,并且在使用Prism应用程序时遇到以下问题:
我有一个类来处理模块从其他模块接收的所有事件。由于课程有两个职责(注册处理程序和处理事件),我决定将课程分成两部分,这导致我公开事件处理程序(这看起来很奇怪)。
在这种情况下你更喜欢什么,在一个班级中有两个职责或者公共事件处理程序(或者我缺少的任何其他东西)?
问候。
修改
public class Handler
{
public void MethodHandlingAggregatedEvent()
{
}
}
public class Register
{
....
public void RegisterHandler()
{
this.eventAggregator.GetEvent<XXX>().Subscribe(this.handler.MethodHandlingAggregatedEvent);
}
}
答案 0 :(得分:3)
为了更好地解释我的答案,请考虑以下示例:
ModuleX
和ModuleY
EventA
和EventB
定义在两个模块都可以访问它们的地方。ModuleX
包含两个事件的事件处理程序。ModuleY
触发这些事件。还要考虑SOLID
(来自Wikipedia)
单一责任原则: 一个班级应该只有一个责任(即只有一个 软件规范的潜在变化应该能够 影响类的规范)
接口隔离原则:“许多客户端特定接口优于一个通用接口。”[4]
映射到此示例时所描述的功能要求为:
如果您有一个同时处理A和B的课程,那么您将违反单一责任原则。如果您使用在同一个类中定义的处理程序注册事件处理程序,那么您也将违反单一责任原则。
那么现在呢?拆分一切将产生四个类,因为这些显然都是不同的职责。根据维基百科,SOLID原则的存在是为了简化扩展和修改现有代码;因此应该让你的生活更轻松,而不是更难。
如果我们创建了四个类,我们就不得不将事件处理程序代码打开到它创建的类之外的作用域。在我看来,保留事件处理代码以及在尽可能小的范围内注册:
class MyHandler
{
public MyHandler(IEventAggregator eventAggregator)
{
eventAggregator.GetEvent<EventA>().Register(HandleEventA);
}
private void HandleEventA(EventArgs args)
{
}
}
MyHandler
现在负责处理EventA
。即使它也在注册处理程序;一个人可能仍然认为这是事件处理程序的一部分。
答案 1 :(得分:0)
我认为你的设计基本上没问题。
Register
负责事件处理程序映射我建议将方法RegisterHandler()
重命名为RegisterHandlers()
以反映其行为。还要使所有类实现接口。所以你可以在单元测试中模仿它们:
_registerMock.Verify(x => x.RegisterHandlers(), Times.Once);
_eventAggregator.Invoke(SomeEvent);
_someHandler.Verify(x => x.MethodHandlingAggregatedEvent(), Times.Once);