在这里,我们正在开发具有特定UI的电子邮件客户端软件,我们需要将其教给用户。
有一些类可以处理应用程序的逻辑。例如,在项目的主要类别之一中就有这样的功能:
public void ComposeMessage(string username,string message)
{
MessageComposer.ComposeMessage(username, message);
}
因此,在上述功能中,我们向用户发送了一条消息。
,但在应用程序的另一侧;有一个辅导阶段。因此,当用户进入应用程序的教程端时,他可以与我们告诉他的应用程序按钮进行交互,但是我们不想发送真实的消息。所以我们像这样改变了上面的功能:
public void ComposeMessage(string username,string message)
{
if(!Global.IsTutorial)
MessageComposer.ComposeMessage(username, message);
}
因此,我们在其主体中添加了许多功能 if(!Global.IsTutorial)
。我们如何避免这种情况?我们不想在教程部分中更改函数的主体,也不想在我们的项目中添加更多的代码和类。我们希望将更改保持在最低水平。
答案 0 :(得分:3)
有很多方法可以实现您想要的,但是所有这些都暗示着,首先,您不直接使用ComposeMessage
,而是为其创建接口并重构调用方以将其作为依赖项注入:
public interface IMessageComposer
{
void ComposeMessage(string username, string message);
}
public class MyApp
{
IMessageComposer messageComposer;
public MyApp(IMessageComposer messageComposer)
{
this.messageComposer = messageComposer;
}
public void Foo()
{
messageComposer.ComposeMessage(username, message);
}
}
当您不依赖具体的实现并注入依赖项时,可以将IMessageComposer
的实现更改为所需的内容,而无需实际触摸原始的MessageComposer
或MyApp
的代码。
例如,您可以像这样创建TutorialMessageComposer
public class TutorialMessageComposer : IMessageComposer
{
public void ComposeMessage(string username, string password)
{
Console.WriteLine("Tutorial mode!");
}
}
和RoutingMessageComposer
装饰器将检查当前模式并调用正确的作曲器
public class RoutingMessageComposer : IMessageComposer
{
IMessageComposer composer;
IMessageComposer tutorialComposer;
public RoutingMessageComposer(IMessageComposer composer, IMessageComposer tutorialComposer)
{
this.composer = composer;
this.tutorialComposer = tutorialComposer;
}
public void ComposeMessage(string username, string message)
{
if (Global.IsTutorial)
tutorialComposer.ComposeMessage(username, message);
else
composer.ComposeMessage(username, message);
}
}
所有准备工作完成后,您只需将RoutingMessageComposer
插入MyApp
var app = new MyApp(new RoutingMessageComposer(new MessageComposer(), new TutorialMessageComposer()));