【发布时间】:2020-10-25 02:12:31
【问题描述】:
我目前不熟悉清洁代码和 SOLID 原则这一主题。
我们为特定任务写了UseCase。
using BusinessLogic.Classes.BusinessLogic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLogic.UseCases
{
public class DoASpecificTask<T> : Interfaces.IUseCase
where T : Interfaces.Connections.IQuery
{
T _Query;
Interfaces.Connections.IConnection<T> _Connection;
object _Parameters;
string _ServiceName;
Interfaces.ISendMessage _MessageSender;
public DoASpecificTask(T query, Interfaces.Connections.IConnection<T> connection, object parameters, string serviceName, Interfaces.ISendMessage messageSender)
{
_Query = query;
_Connection = connection;
_Parameters = parameters;
_ServiceName = serviceName;
_MessageSender = messageSender;
}
public void Execute()
{
Interfaces.Connections.IQueryResultList resultList = ExecuteReadDataOnConnection<T>.GetList(_Query, _Connection, _Parameters);
if (!ValidateQueryResultListItems.Validate(resultList))
{
EndImp3Service.EndService(_ServiceName);
_MessageSender.SendMessage('Message','for@bar.com');
}
}
}
}
据我了解 SOLID,解决方案/类/方法应该对扩展开放,对更改关闭(开放/封闭原则)。我们现在的问题是,我们创建了一个不具体的通用interface 用于发送消息
Interfaces.ISendMessage:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLogic.Interfaces
{
public interface ISendMessage
{
void SendMessage(string message, string recipient);
}
}
实际上,我们想通过电子邮件发送消息,因此我们创建了另一个接口ISendEmail,它实现了ISendMessage。邮件还有一个参数subject,在通用接口ISendMessage中没有实现(方法SendMessage())。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BusinessLogic.Interfaces
{
public interface ISendEmail : ISendMessage
{
void SendMessage(string message, string recipient, string subject);
}
}
现在我的问题是,我们如何才能在 UseCase 中不明确以保持对扩展的开放?可能是,在某些时候我们想要发送 WhatsApp 或 Telegram 消息而不是电子邮件。如果我在UseCase 中实现ISendMessage 的属性,我就没有subject 的参数。
我的意思是UseCase中的这一行:
_MessageSender.SendMessage('Message','for@bar.com');
因为我们指定了通用接口ISendMessage,所以我们不能在方法中提供subject。如果我们将ISendMessage 更改为ISendEmail,我们就不再营业了,不是吗?
这是怎么做到的,还是我们误解了一些完全错误的东西?
更新
首先,感谢您的 cmets 和解决方案。我认为,这正是我们作为 SOLID 初学者需要了解的问题,什么时候要具体化,而不是试图制作一个在任何情况下都可以做任何事情的程序。当然,SOLID 并不是说完全不改代码,问题是哪里需要改代码。
我认为,在所有提供的解决方案中,问题只是转移了。无论如何,我需要指定我在UseCase 中使用的确切类型。如果我要使用@Martin Verjans 的解决方案,我可以使用IMessage 类型,但是我必须在参数中具体说明。通过使用generics,我遇到了同样的问题。 @SomeBody 的解决方案,不符合 Open/Closed 原则。
我们的目标是在UseCase 中实现不特定,这样如果我们决定发送 WhatsApp 消息而不是电子邮件,我们就不需要更改 UseCase 本身。实际上我没有看到这个选项。
【问题讨论】:
-
恕我直言:所有原则都只是抽象的,它们与任何语言都没有关系,所以你应该找到一种方法来实现它们。在这种情况下,您有 2 个参数,WHOM 和 WHAT。它可能不仅仅是字符串,它可能是复杂的对象或标识符。但是每个继承者将决定使用哪些字段。
-
@EgorPopov 是的,我知道,
SOLID并不特定于任何语言,而且我也知道,我也可以传递复杂的参数。但我不认为,这有助于解决这个问题。如果您有兴趣,请阅读我在原帖中的更新。
标签: c# solid-principles