重构 C# 代码(帮助改进)
本文关键字:帮助 代码 重构 | 更新日期: 2023-09-27 18:32:16
我需要帮助来重构此代码示例的某些部分,以便从if (_obj is Application)
的位置重构,以便这将是通用的。
public override void Body(object _obj, object _objInPreviousState)
{
if (_obj != null)
{
string Message = "";
string Subject = "";
if (_objInPreviousState == null)
{
var emailParams = this.Param as Dictionary<string, string>;
if (emailParams != null)
{
Message = emailParams["Message"];
Subject = emailParams["Subject"];
}
}
var emails = userRepository().GetForRoles("RM").Select(c => c.Email);
if (_obj is Application)
{
var app = (Application)_obj;
var appInPreviousState = _objInPreviousState as Application;
if (appInPreviousState == null)
{
emailService().SendEmails("aps@somedomain.com", emails.ToArray(), Message, Subject);
}
else if (app.ApplicationStatus != appInPreviousState.ApplicationStatus)
{
emailService().SendEmails("aps@somedomain.com", emails.ToArray(), "Application: " + app.ID + " changed decision status: " + Enum.GetName(typeof(AppStatus), app.ApplicationStatus), "Check following application: " + app.ID);
}
}
else if (_obj is Product)
{
var product = (Product)_obj;
var prodInPreviousState = _objInPreviousState as Product;
if (prodInPreviousState == null)
{
emailService().SendEmails("aps@somedomain.com", emails.ToArray(), Message, Subject);
}
else if (product.ProductStatusType != prodInPreviousState.ProductStatusType)
{
emailService().SendEmails("aps@somedomain.com", emails.ToArray(), "Product: " + product.ID + " for application " + product.ApplicationID + " changed decision status: " + Enum.GetName(typeof(AppStatus), product.ProductStatusType), "Check following application: " + product.ApplicationID);
}
}
else if (_obj is CES)
{
var ces = (CES)_obj;
var cesInPreviousState = _objInPreviousState as CES;
if (cesInPreviousState == null)
{
emailService().SendEmails("aps@somedomain.com", emails.ToArray(), Message, Subject);
}
else if (ces.Status != cesInPreviousState.Status)
{
emailService().SendEmails("aps@somedomain.com", emails.ToArray(), "CES for application " + ces.ApplicationID + " changed decision status: " + Enum.GetName(typeof(CesStatuses), ces.Status), "Check following application: " + ces.ApplicationID);
}
}
else if (_obj is Comment)
{
var comment = (Comment)_obj;
emailService().SendEmails("aps@somedomain.com", emails.ToArray(), "Comment for the following application: " + comment.ApplicationID + " with message: " + comment.Message + " on date: " + comment.CreatedDate, "Comment for the following application: " + comment.ApplicationID);
}
mLog.InfoLine("Sendet Email");
}
}
您可能应该使用一些接口,我没有为您提供完整的代码,而是要遵循的模式。
interface IStatusItem
{
void SendEmails(EmailService service);
}
public class Product : IStatusItem
{
public void SendEmails(EmailService service)
{
// Send Email
}
}
public class Application : IStatusItem
{
public void SendEmails(EmailService service)
{
// Send Email
}
}
然后你的主代码不需要所有的if块。它只是调用IStatusItem实例上的实现。显然,您需要在其中添加以前的状态。
override void Body(object _obj, object _objInPreviousState)
{
IStatusItem sItem = obj as IStatusItem;
if(sItem != null)
sItem.SendEmails(emailService());
}
您可以轻松改进两件事:
首先,反转一些if
以减少嵌套。特别:
if (_obj != null) { ... the entire function ... }
可以
if (null == _obj) { return; }
... the rest ...
此外,将每个 if/else 主体提取到单独的方法中(您只需选择主体并选择重构...从菜单中提取方法。
最后,您应该能够将所有这些方法概括为一个需要更多参数的方法。
在这种情况下,
您可以创建一个生产对象的工厂。
这就是我重构的方式:
SomethingFactory 生产 AbstractSomething 派生类(ConcreteSomethingA、ConcreteSomethingB 等)。工厂根据"_obj"和
public override void Body(object _obj, object _objInPreviousState)
将在具体类中实现,因此系统可以轻松扩展
- 反_obj为
if ( _obj == null ) return;
- 将
""
声明替换为string.Empty
- 使用字符串。格式化以格式化具有大量串联的字符串
- 将电子邮件地址提取到配置文件
-
创建项目的界面
public interface IEmail{ string GetMessage(); string GetSubject(); }
-
创建工厂以生成
IEmail
实例 -
在一次通话中发送电子邮件
public void Body(object obj, object objInPreviousState) { const string Address= "aps@somedomain.com"; //extract to configuration IEmail item = GetEmailItem(_obj, _objInPreviousState); if(item != null) emailService().SendEmails( Address, emails.ToArray(), item.GetMessage(), item.GetSubject() ); }