我有一个名为MessageService的类。该类负责接收电子邮件(实际流程)。根据邮件的主题,它会检测哪个流程受到威胁并执行操作。
解释我的问题的一些代码可能更简单:
public class MessageService
{
public void ReadEmail()
{
switch (subject)
"1" :
Myservice.action1(); break;
"2" :
Myservice.action2(); break;
"qwwerty" :
MyOtherservice.Querty(); break;
etc...
}
}
为了进行一些控制反转,我想通过我的类MessageService的构造函数传递对服务的引用。
public MessageService(IMyService myService,IMyOtherservice myOtherservice, ect....)
{
Myservice=myService;
MyOtherservice=myOtherservice;
}
它适用于一些引用,但MessageService类可能会处理多达20,30或40个不同的流。这会使我的班级的初始化有点沉重。
有没有更好的方法来实现它?通过一些设计模式?我应该关心IOC(不过,我喜欢在课后运行我的测试......)?
感谢您的帮助,
答案 0 :(得分:0)
您可能希望使用责任链设计模式。创建一个知道如何处理电子邮件的接口,并为你想要做的每个任务构建单独的类(大致相当于你的switch语句(switch
,顺便说一句,是一个非常天真的COR实现))。这些课程每个都只接受他们需要的服务。然后在MessageService
中获取这些接口的列表并一次处理一个接口,直到其中一个接口指示它已处理它:
public interface IMessageReader
{
/// <returns><c>true</c> if handled; otherwise false
bool ReadEmail(Mail message);
}
public class QwertyMessageReader : IMessageReader
{
public QwertyMessageReader(IMyOtherService otherService) {/*set*/}
public bool ReadEmail(Mail message)
{
if(message.Subject.Equals("qwwerty"))
{
otherService.Querty();
return true;
}
return false;
}
}
public class MessageService
{
public MessageService(IEnumerable<IMessageReader> readers) {/*set*/}
public void ReadEmail()
{
var handled = readers.Select(reader => reader.ReadEmail(message))
.FirstOrDefault(result => result);
}
}
您需要调整上面的界面和代码以适合您的工作,但这是主要概念。
大多数体面的IOC容器都会自动生成IEnumerable&lt;&gt;如果您注册了多个相同的界面,请为您服务。
答案 1 :(得分:0)
最好的建议是将你的班级分成更小的班级。在一个类中有30或40个依赖关系表明它做得太多了。尝试将每个类分解成只做一件事的事情,然后你可以开始将它们组合成更大的功能。由于您使用的是IoC容器,因此实际上这应该不会太难,并且会使您的代码更容易测试。理想的目标是为每个班级拍摄一两个依赖项,但实际上,我认为4或5是一个很好的目标。
不知道您的代码到底在做什么,很难建议具体的设计模式。