c# - 使用设计模式重构多个变量

标签 c# dictionary factory-pattern solid-principles strategy-pattern

在我之前的question关于电子邮件服务,只有一个可变性,即 emailType。现在我还有一个可变性,即传递给策略的可变性。它可以是 customerIdorderIdcancellationId,如下所示。

客户端不必传递所有参数。有些可以是 null。例如,尽管 emailType 可以是 CancellationEmail,但 cancellationId 可以为 null。

class EmailService
{
    Send(int emailType, int? customerId, int? orderId, int? cancellationId = null)
    {
        switch(emailType)
        {
            case 1: SendSignupEmail(customerId);
                break;
            case 2: SendOrderEmail(customerId, orderId);
                break;
            case 3: SendCancellationEmail(orderId, cancellationId);
                break;
        }
    }

    SendSignupEmail(int? customerId);
    SendOrderEmail(int? customerId, int? orderId = null);
    SendCancellationEmail(int? orderId, int? cancellationId);
}

我看到的这个问题的解决方案是应用策略模式,但使用字典

interface ISendEmail
{
    Send(dictionary allIds);
}

但这将强制客户端(调用 EmailService 的应用程序)创建 dictionary。我可以将该字典创建移动到 Factory 方法。

如何通过应用 SOLID 原则更好地重构这段代码?

我愿意使用像 Unity 这样的容器来解决它,以消除一些手动对象构造。

最佳答案

我认为您错误地应用了 SOLID。您正在创建一个不能与相同意图互换的抽象。如果您为注册电子邮件创建了一个 ISendMail 实现,则无法将其取出并替换为发送订单电子邮件的实现。它采用不同的参数,更重要的是,功能意图不同。因此它应该需要不同的抽象。

我会创建以下抽象:

public interface ISignupEmailSender { void Send (int customerId); }
public interface IOrderEmailSender { void Send (int customerId, int orderId); }
public interface ICancellationEmailSender { void Send (int orderId, int cancellationId); }

为抽象添加实现,并在需要时注入(inject)它们。

现在,如果你想创建一个代理/服务来有一个发送所有电子邮件的地方,那么创建IEmailService抽象,并注入(inject)上面的email-sender,并为每个添加一个相应的方法电子邮件发件人。就像您在当前的电子邮件发件人中使用的一样,但没有您当前使用的 void Send(int, int?, int?, int?) 方法。

对于具有不同幕后实现的不同抽象,使用具有多个参数的单一方法不会获得任何好处。它只会让事情变得复杂。保持简单。

关于c# - 使用设计模式重构多个变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42808826/

相关文章:

c# - 在跟踪查询数量时维护 CQS

java - 以线程安全的方式延迟初始化 Java 映射

python - 如何组合多个字典,在 Python 中对公共(public)键的值求和(并保留值为 0 的值)?

python - 如何使用某些键对列表中的值求和?

android - 如何在 Android 中实现 ViewModel 工厂

java - 基于套接字的消息工厂

c# - 使用 csvHelper 序列化子类

c# - 如何使用 C# 在不同的处理器中运行线程?

c# - 'OFFSET' 附近的语法不正确。 FETCH 语句中 NEXT 选项的无效使用 "in Entity Framework core"

javascript - 工厂未定义