但今天,我们将用C#的“解剖刀”,揭开:
// 错误示例:可维护性杀手(反模式)
public class OrderProcessor {
public void ProcessOrder(string orderJson) {
// 直接操作数据库
var conn = new SqlConnection("connStr");
conn.Open();
// 直接反序列化
var order = JsonConvert.DeserializeObject<Order>(orderJson);
// 直接调用邮件服务
SendEmail(order.CustomerEmail, "Order Placed");
}
private void SendEmail(string email, string subject) {
// 直接创建SMTP客户端
new SmtpClient("smtp.gmail.com").Send("[email protected]", email, subject, "");
}
}
// 正确方案:可维护性架构(附带生存指南)
public class OrderProcessor {
private readonly IOrderRepository _repo;
private readonly IEmailService _emailService;
public OrderProcessor(IOrderRepository repo, IEmailService emailService) {
_repo = repo;
_emailService = emailService;
}
public async Task ProcessOrderAsync(string orderJson) {
var order = await DeserializeOrder(orderJson);
await _repo.SaveAsync(order);
await _emailService.SendAsync(order.CustomerEmail, "Order Placed");
}
private async Task<Order> DeserializeOrder(string json) {
// 使用模式匹配验证
return await Task.FromResult(JsonConvert.DeserializeObject<Order>(json));
}
}
接下来,我们将用"可维护性解剖刀"的七大核心——模块化设计、依赖管理、测试策略、文档与重构、性能监控、架构演化、实战案例,打造能活过10年的代码!
“我改了个按钮颜色,数据库连接就崩了!”
// 代码1:模块化架构(推荐)
public interface IOrderService {
Task ProcessOrderAsync(string json);
}
public class OrderService : IOrderService {
private readonly IOrderRepository _repo;
private readonly IEmailService _email;
public OrderService(IOrderRepository repo, IEmailService email) {
_repo = repo;
_email = email; // 依赖解耦
}
// 业务逻辑
}
public interface IEmailService {
Task SendAsync(string to, string subject);
}
// 依赖注入配置
public class Startup {
public void ConfigureServices(IServiceCollection services) {
services.AddScoped<IOrderService, OrderService>();
services.AddScoped<IOrderRepository, EfOrderRepository>();
services.AddScoped<IEmailService, GmailService>(); // 可替换为其他实现
}
}
注释解释:
IOrderService
定义业务接口,OrderService
实现具体逻辑EfOrderRepository
和GmailService
是基础设施实现AddScoped
实现依赖注入,替换实现无需修改代码“我的服务层直接调用UI控件,数据库层依赖日志库!”
// 代码2:依赖倒置架构
public class DependencyInversionExample {
// 高层模块依赖抽象
public class UI {
private readonly IProcessor _processor;
public UI(IProcessor processor) => _processor = processor;
public void OnClick() => _processor.Execute();
}
// 低层模块实现抽象
public class DatabaseProcessor : IProcessor {
private readonly IConnectionFactory _conn;
public DatabaseProcessor(IConnectionFactory conn) => _conn = conn;
public void Execute() => _conn.CreateConnection().Query();
}
// 接口定义
public interface IProcessor { void Execute(); }
public interface IConnectionFactory { IDbConnection CreateConnection(); }
}
注释解释:
UI
层不直接依赖DatabaseProcessor
,而是依赖抽象接口IProcessor
IConnectionFactory
抽象数据库连接,可替换为IDbConnection
或Dapper
实现“我的测试覆盖率90%,但还是每天有10个BUG!”
// 代码3:TDD测试驱动开发
[TestFixture]
public class OrderServiceTests {
private Mock<IOrderRepository> _repoMock;
private Mock<IEmailService> _emailMock;
private OrderService _service;
[SetUp]
public void Setup() {
_repoMock = new Mock<IOrderRepository>();
_emailMock = new Mock<IEmailService>();
_service = new OrderService(_repoMock.Object, _emailMock.Object);
}
[Test]
public async Task ProcessOrder_SavesToRepo() {
// Arrange
var json = "{\"Id\":1}";
// Act
await _service.ProcessOrderAsync(json);
// Assert
_repoMock.Verify(r => r.SaveAsync(It.IsAny<Order>()), Times.Once);
_emailMock.Verify(e => e.SendAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
}
}
// 代码4:性能测试(xUnit)
public class PerformanceTests {
[Fact]
public void ProcessOrder_MustBeFast() {
var watch = new Stopwatch();
watch.Start();
// 测试代码
watch.Stop();
Assert.LessThan(watch.ElapsedMilliseconds, 50); // 50ms内完成
}
}
注释解释:
Moq
框架模拟依赖,测试业务逻辑独立性xUnit
支持async/await
和Fact
/Theory
多维度测试Stopwatch
和Assert
断言“三年前写的代码,连我都不记得参数含义!”
// 代码5:XML文档示例
///
/// 处理订单并发送通知
///
/// 订单JSON字符串,必须包含Id和CustomerEmail字段
/// 订单处理结果
/// 当orderJson为null时抛出
public async Task<OrderResult> ProcessOrderAsync(string orderJson) {
// 业务逻辑
}
// 代码6:重构示例(使用命名元组)
public class OrderService {
public async Task<OrderResult> ProcessOrderAsync(string json) {
// 1. 解析订单
var order = await DeserializeOrder(json); // 提取方法
// 2. 保存到数据库
await _repo.SaveAsync(order); // 依赖注入
// 3. 发送邮件
await _email.SendAsync(order.CustomerEmail, "Order Placed"); // 使用接口
return new OrderResult { Status = "Success" };
}
private async Task<Order> DeserializeOrder(string json) {
// 使用模式匹配验证
return await Task.FromResult(JsonConvert.DeserializeObject<Order>(json));
}
}
注释解释:
DeserializeOrder
提升可读性OrderResult
代替void
返回结果“每秒100个请求还能跑,1000个就挂了!”
// 代码7:性能监控(Serilog+Prometheus)
public class PerformanceMonitor {
private readonly ILogger _logger;
private readonly IPerformanceCounter _counter;
public PerformanceMonitor(ILogger logger, IPerformanceCounter counter) {
_logger = logger;
_counter = counter;
}
public async Task ProcessOrderWithMetrics(string json) {
var sw = Stopwatch.StartNew();
try {
await _service.ProcessOrderAsync(json);
_counter.Record("OrderProcessing:Success");
} catch (Exception ex) {
_counter.Record("OrderProcessing:Failure");
_logger.Error(ex, "Order processing failed");
} finally {
_counter.RecordDuration("OrderProcessing:Duration", sw.Elapsed.TotalMilliseconds);
}
}
}
// 代码8:日志结构化(Serilog)
public class LoggerExample {
private readonly ILogger _logger;
public LoggerExample(ILogger logger) => _logger = logger;
public void LogOrderProcessing(string orderId, bool success) {
_logger.Information(
EventId = 1001,
"Order {OrderId} processed with status {Success}",
orderId, success ? "Success" : "Failure"
);
}
}
注释解释:
Serilog
支持结构化日志,便于ELK栈分析PerformanceCounter
可与Prometheus集成“我们用了5年的架构,现在连加个字段都要改20个地方!”
// 代码9:CQRS架构示例
public class OrderWriteModel {
// 命令处理层(CQRS写模型)
public async Task PlaceOrderAsync(PlaceOrderCommand cmd) {
var order = new Order(cmd.OrderId, cmd.CustomerId);
await _repo.SaveAsync(order);
await _bus.Publish(new OrderPlacedEvent(order)); // 发布领域事件
}
}
public class OrderReadModel {
// 查询层(CQRS读模型)
public async Task<OrderSummary> GetOrderSummaryAsync(string orderId) {
var order = await _queryRepo.GetOrder(orderId);
return new OrderSummary { Id = order.Id, Status = order.Status };
}
}
// 代码10:事件溯源(ES)
public class OrderSourced {
private readonly List<OrderEvent> _events = new();
public void Apply(PlaceOrderEvent @event) {
_events.Add(@event);
// 重建状态
Id = @event.OrderId;
CustomerId = @event.CustomerId;
}
public void LoadFromHistory(IEnumerable<OrderEvent> history) {
foreach (var @event in history) {
Apply(@event);
}
}
}
注释解释:
OrderEvent
重建状态,支持回滚PlaceOrderCommand
和OrderPlacedEvent
解耦命令与事件需求背景:
“我们的电商系统有100万行代码,但每次改价都要停机1小时!”
优化方案:
关键代码:
// 代码11:微服务架构(ASP.NET Core)
public class Startup {
public void ConfigureServices(IServiceCollection services) {
services.AddControllers();
services.AddOpenApiDocument(); // Swagger支持
services.AddGrpc(); // gRPC通信
services.AddHealthChecks(); // 健康检查
}
public void Configure(IApplicationBuilder app) {
app.UseRouting();
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
endpoints.MapGrpcService<OrderService>();
});
}
}
// 代码12:事件总线集成(MassTransit)
public class OrderService : IOrderService {
private readonly IBus _bus;
public OrderService(IBus bus) => _bus = bus;
public async Task PlaceOrderAsync(PlaceOrderCommand cmd) {
// 业务逻辑
await _bus.Publish(new OrderPlacedEvent(cmd.OrderId)); // 发布事件
}
}
性能对比:
指标 | 传统架构 | 可维护架构 | 改进幅度 |
---|---|---|---|
停机时间/次 | 1小时 | 1分钟 | 99% |
新增功能时间 | 2周 | 2天 | 90% |
单元测试覆盖率 | 15% | 85% | +70% |
// 代码13:上帝类反模式
public class OrderManager {
public void ProcessOrder() { /* 1000行代码 */ }
public void SaveToDatabase() { /* 另500行 */ }
// ...
}
// 解决方案:拆分为职责单一的类
public class OrderProcessor { public void Process() { /* 仅处理业务 */ } }
public class OrderRepository { public void Save() { /* 仅保存数据 */ } }
// 代码14:循环依赖反模式
public class A { public B B { get; set; } }
public class B { public A A { get; set; } }
// 解决方案:引入中间接口
public interface ISharedService { void DoSomething(); }
public class A { private readonly ISharedService _service; }
public class B { private readonly ISharedService _service; }
// 代码15:硬编码反模式
public class DatabaseConfig {
public string ConnectionString => "Server=localhost;Database=Orders;...";
}
// 解决方案:配置注入
public class DatabaseConfig {
public string ConnectionString { get; set; } // 从appsettings读取
}
// 代码16:无类型日志反模式
Console.WriteLine("Error: Order 123 failed");
// 解决方案:结构化日志
_logger.LogError("Order {OrderId} failed", 123); // Serilog支持
// 代码17:可维护性评分工具
public class CodeHealthChecker {
public static double CalculateScore(string projectPath) {
var linesOfCode = GetLinesOfCode(projectPath); // 代码行数
var cyclomaticComplexity = GetComplexity(projectPath); // 圈复杂度
var testCoverage = GetTestCoverage(); // 测试覆盖率
return (1 / linesOfCode) * 0.3 +
(1 / cyclomaticComplexity) * 0.5 +
testCoverage * 0.2;
}
}
注释解释:
// 代码18:重构工具链
public class RefactoringPipeline {
public void Run() {
// 1. 自动提取方法
RoslynRewriter.ExtractMethod("OrderProcessor.cs", "ProcessOrder");
// 2. 自动注入依赖
DependencyInjector.Inject("Startup.cs", "IOrderService");
// 3. 自动添加日志
LoggerInjector.Inject("OrderService.cs", "ProcessOrder");
}
}
注释解释:
当我们在C#中构建可维护架构时,本质上是在打造“代码的长寿基因”: