我有一个要求,即用户需要配置他们希望在发生错误时收到警报的方式。他们拥有的选项如下:
1。)在事件日志中创建一个事件
2.。)向用户界面指定的电子邮件发送电子邮件
我目前使用的类使用以下界面
interface INotificationSender
{
virtual void SendMessage(string message);
}
我的界面将由以下2个具体类
实现class EmailerNotificationSender: public INotificationSender
{
string m_EmailAddress;
public EmailerNotificationSender(string emailAddress)
{
m_EmailAddress = emailAddress;
}
public virtual void SendMessage(string Message)
{
// Send Message to email specified in member variable
}
}
class EventLogNotificationSender: public INotificationSender
{
public virtual void SendMessage(string Message)
{
// Log message in event log using
}
}
我当前的界面代码如下所示
public class MyUserinterfaceWindow
{
private INotificationSender m_NotificationSender; // concrete type depends on user interface selection!
public void Button_Click(...)
{
if (emailSelected)
{
m_NotificationSender = new EmailerNotificationSender(textbox.email)
return;
}
m_NotificationSender = new EventLogNotificationSender();
}
public void SendAlert()
{
m_NotificationSender.SendMessaged("SOMETHING BAD HAPPENED");
}
}
概要/问题: 如何删除实例化的具体类型(例如EventLogNotificationSender和EmailerNotificationSender)
注意:当EmailNotificationSender的具体构造函数采用字符串参数时,EventLogNotificationSender在其具体构造函数中不需要参数!
答案 0 :(得分:0)
隐藏composite INotificationSender
实施背后的两个实现。
如果您可以延迟用户选择他想要记录的源,您可以将该选择逻辑移动到复合中,这可以防止此逻辑混乱MyUserinterfaceWindow
。这是一个例子:
public class CompositeNotificationSender : INotificationSender {
private readonly EmailerNotificationSender mailer;
private readonly EventLogNotificationSender eventLogger;
public CompositeNotificationSender(
EmailerNotificationSender mailer,
EventLogNotificationSender eventLogger) {
this.mailer = mailer;
this.eventLogger = eventLogger;
}
public virtual void SendMessage(string Message) {
bool logToMail = AskUserWhereToLog();
var logger = logToMail ? this.mailer : this.eventLogger;
logger.SendMessage(Message);
}
private bool AskUserWhereToLog() {
// TODO:
}
}
由于此类询问用户,因此UI存在依赖关系,此类是特定于UI的。如果这不是一个选项,也可以提取。当然,如果您愿意,可以通过缓存结果来防止不得不多次询问用户。
如果要求用户及时处理不起作用,您可以创建CompositeNotificationSender
和MyUserinterfaceWindow
都可以依赖的抽象,以保持用户的偏好:
public interface IUserLoggingPreference
{
bool LogToMail { get; set; }
}
MyUserinterfaceWindow
(或任何其他地方)现在可以依赖IUserLoggingPreference
并更改LogToMail
值以更改用户的偏好。 CompositeNotificationSender
将如下所示:
public class CompositeNotificationSender : INotificationSender {
private readonly IUserLoggingPreference preference;
private readonly EmailerNotificationSender mailer;
private readonly EventLogNotificationSender eventLogger;
public CompositeNotificationSender(
IUserLoggingPreference preference,
EmailerNotificationSender mailer,
EventLogNotificationSender eventLogger) {
this.preference = preference;
this.mailer = mailer;
this.eventLogger = eventLogger;
}
public virtual void SendMessage(string Message) {
var logger = this.preference.LogToMail ? this.mailer : this.eventLogger;
logger.SendMessage(Message);
}
}
这样,用户无需在单击按钮后提示,CompositeNotificationSender
独立于用户界面,这样可以更轻松地重用此逻辑(例如,在系统的一部分中)没有用户交互的地方)它可以更容易地对这个类进行单元测试。