gpt4 book ai didi

c# - C# 中的 SOLID 原则 - 如何实现更具体的接口(interface)

转载 作者:行者123 更新时间:2023-12-03 16:47:44 27 4
gpt4 key购买 nike

我目前对清洁代码和 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);
}
}
实际上,我们想通过电子邮件发送消息,所以我们创建了另一个接口(interface) ISendEmail , 实现 ISendMessage .电子邮件还有一个参数 subject ,在通用接口(interface) 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 消息而不是电子邮件。如果我实现 ISendMessage 的属性在 UseCase ,我没有参数 subject .
我的意思是 UseCase 中的这一行:
_MessageSender.SendMessage('Message','for@bar.com');
因为我们指定了通用接口(interface) ISendMessage ,我们无法提供 subject在方法中。如果我们更改 ISendMessageISendEmail ,我们不再开放,不是吗?
怎么能做到这一点,或者我们误解了一些完全错误的东西?

更新
首先,感谢您的意见和解决方案。我认为,这正是我们作为 SOLID 初学者需要了解的问题,什么时候要具体化,而不是试图制作一个在任何情况下都可以做任何事情的程序。当然,SOLID 并不意味着完全没有代码更改,但问题是 在哪里 代码需要更改。
我认为,在所有提供的解决方案中,问题只是转移了。无论如何,我需要在 UseCase 中指定我使用的确切类型。 .如果我要使用@Martin Verjans 的解决方案,我可以使用类型 IMessage ,但是我必须在参数中具体说明。通过使用 generics , 我有同样的问题。 @SomeBody 的解决方案,不符合开放/封闭原则。
我们的目标是在 UseCase 中实现不具体。 , 这样我们就不需要更改 UseCase本身,如果我们决定发送 WhatsApp 消息而不是电子邮件。实际上我没有看到这个选项。

最佳答案

我想要问的第一个问题是:“ISendMessage 接口(interface)的真正目的是什么?”
如果要能够通过任何有效的方式发送任何消息,也许仅仅有一个消息和一个接收者是不够的。在这种情况下,您可以在通用界面中添加主题。
如果您有许多不同的方式来发送此消息并且其中一些不需要主题,那么可能是实现 ISendEMail 以生成主题的类的角色。
如果您真的想保持通用,也许您可​​以将此接口(interface)与一个工厂结合起来,该工厂将根据给定的参数生成适当的接口(interface)。
另一种选择是拥有一个将传递给 ISendMessage 的 IMessageParameters 接口(interface),如下所示:

public interface IMessageParameters
{
}

public interface ISendMessage
{
void SetParameters(IMessageParameters);
void SendMessage(string message);
}
那么对于 ISendEmail 接口(interface),您将需要一个特定的 IMessageParameters :
public interface ISendEmailParameters : IMessageParameters
{
string recipient { get; set;}
string subject { get; set;}
}
这一切都取决于您在这里真正想要实现的目标。尽管 SOLID 原则可以帮助您极大地整合您的代码,但不要试图创建一个在任何情况下都可以做任何事情的程序。
还记得 KISS principle ,如果你的程序现在只发送电子邮件并且总是需要一个主题,把它放在你的通用界面中。
最后一句话:开放扩展,接近修改并不意味着永远不会更改您的源代码。这实际上意味着一旦构建了一个方法,您将不会更改该方法。但是您可以添加一个方法来做一些不同的事情或添加一个新功能。
更新
阅读您的更新后,我认为最好的解决方案是将主题作为 ISendMessage 接口(interface)的一部分。原因是您发送的任何消息都有主题。这也适用于一般生活,每当您与某人交谈时,您都想提出一个主题……
因此,实现者有责任以他们想要的方式对待主题:
  • 电子邮件发件人会将其放入主题字段
  • WhatsApp 发件人可以将其作为消息的第一行
  • SMS 发件人可以忽略它
  • 任何人都必须对待他们发送带有主题的消息的方式。
  • 关于c# - C# 中的 SOLID 原则 - 如何实现更具体的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64457219/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com