CleanArchitecture代码重构实战:5种常见坏味道识别与修复指南
CleanArchitecture作为.NET Core领域优秀的架构模板项目,遵循干净架构原则,为开发者提供了清晰的分层结构和最佳实践。但在实际代码中,我们仍然可以发现一些需要重构的"坏味道"。本文将深入分析CleanArchitecture项目中的代码问题,并提供实用的重构解决方案。
🔍 1. 暴露的内部事件类
在ContributorDeletedEvent.cs文件中,我们发现一个典型的架构问题:
// NOTE: Would prefer this be internal but Mediator Source Generator needs access to it from elsewhere.
public class ContributorDeletedEvent : INotification
{
public ContributorId ContributorId { get; }
public string Name { get; }
public ContributorDeletedEvent(ContributorId contributorId, string name)
{
ContributorId = contributorId;
Name = name;
}
}
问题分析:事件类本应设计为internal,但由于Mediator源代码生成器的限制,被迫公开。
重构建议:考虑使用接口隔离或适配器模式,将内部实现细节隐藏,只暴露必要的契约。
🎯 2. 原始痴迷与值对象缺失
在早期的Contributor类设计中,存在典型的"原始痴迷"坏味道:
public class Contributor : EntityBase, IAggregateRoot
{
public string FirstName { get; private set; } = string.Empty;
public string LastName { get; private set; } = string.Empty;
// 业务逻辑散落在各处
public string GetFullName() => $"{FirstName} {LastName}";
}
问题分析:将姓名拆分为FirstName和LastName两个原始字符串,导致业务逻辑分散。
重构方案:项目已通过ContributorName.cs实现了值对象模式:
public class ContributorName : ValueObject
{
public string FirstName { get; }
public string LastName { get; }
public ContributorName(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public string FullName => $"{FirstName} {LastName}";
protected override IEnumerable<object> GetEqualityComponents()
{
yield return FirstName;
yield return LastName;
}
}
📝 3. 魔法字符串与常量管理
在Constants.cs中,项目展现了良好的常量管理实践:
public static class CacheKeys
{
public const string ContributorList = "contributor-list";
public const string ContributorById = "contributor-by-id-{0}";
}
public static class ValidationMessages
{
public const string RequiredField = "{0} is required";
public const string InvalidEmail = "Invalid email format";
}
最佳实践:将所有魔法字符串集中管理,提高代码可维护性和可读性。
🚀 4. 空值检查的现代化重构
传统的大量null检查代码:
if (contributor == null)
{
throw new ArgumentNullException(nameof(contributor));
}
重构方案:使用C#现代语法糖和Guard子句:
public Contributor UpdateName(ContributorName name)
{
ArgumentNullException.ThrowIfNull(name);
Name = name;
AddDomainEvent(new ContributorNameUpdatedEvent(Id, name.FullName));
return this;
}
🔧 5. 集合初始化的优化
避免在循环中频繁创建集合:
// 反模式
var items = new List<string>();
foreach (var item in source)
{
items.Add(ProcessItem(item));
}
// 优化方案
var items = source.Select(ProcessItem).ToList();
💡 重构总结与建议
CleanArchitecture项目在架构设计上已经相当优秀,但仍有一些细节可以优化:
- 领域事件可见性:探索使用接口或抽象基类来限制内部实现的暴露
- 值对象广泛应用:在合适的地方继续推广值对象模式
- 现代C#特性:充分利用C#的最新特性简化代码
- 测试覆盖:确保重构后的代码有充分的测试保障
通过识别和修复这些代码坏味道,可以进一步提升CleanArchitecture项目的代码质量和可维护性。记住,重构是一个持续的过程,需要结合具体业务场景和团队规范来进行。
架构优势:CleanArchitecture的分层设计(Core、Infrastructure、UseCases、Web)为代码重构提供了良好的基础,每层职责单一,便于定位和修复问题。
开始你的代码重构之旅吧!🚀
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



