架构师的核心不是画图,而是在约束下做权衡。业务要快、成本要低、系统要稳、团队要能维护——这些目标经常冲突。架构师的职责,就是识别关键约束,做出可解释、可演进、可落地的技术决策。
下面以电商订单系统为例,展示从需求到代码的架构落地过程。
业务需求:
关键约束:交付周期短、团队规模小、业务变化快。因此架构目标不是“大而全”,而是清晰分层、依赖倒置、易于替换。
记录为 ADR(架构决策记录):
ADR-001:采用分层架构 + 依赖倒置
状态:已接受
背景:业务变化快,需替换支付渠道和存储
决策:领域层定义接口,基础设施层实现
后果:增加少量接口代码,换取可测试性和可替换性package domain;
import java.time.Instant;
import java.util.List;
public class Order {
private final String id;
private OrderStatus status;
private final List<OrderItem> items;
private final Instant createdAt;
public Order(String id, List<OrderItem> items) {
this.id = id;
this.items = List.copyOf(items);
this.status = OrderStatus.CREATED;
this.createdAt = Instant.now();
}
public void pay() {
if (status != OrderStatus.CREATED) {
throw new IllegalStateException("only created order can pay");
}
this.status = OrderStatus.PAID;
}
public void cancel() {
if (status == OrderStatus.PAID) {
throw new IllegalStateException("paid order cannot cancel directly");
}
this.status = OrderStatus.CANCELLED;
}
public String id() { return id; }
public OrderStatus status() { return status; }
public List<OrderItem> items() { return items; }
}package domain;
public interface OrderRepository {
void save(Order order);
Order findById(String id);
}package domain;
public interface PaymentGateway {
PaymentResult pay(String orderId, Money amount);
}领域层只定义“做什么”,不关心“怎么做”。
package application;
import domain.*;
public class OrderApplicationService {
private final OrderRepository repository;
private final PaymentGateway paymentGateway;
private final EventPublisher publisher;
public OrderApplicationService(OrderRepository repository,
PaymentGateway paymentGateway,
EventPublisher publisher) {
this.repository = repository;
this.paymentGateway = paymentGateway;
this.publisher = publisher;
}
public void pay(String orderId) {
Order order = repository.findById(orderId);
PaymentResult result = paymentGateway.pay(orderId, order.total());
if (!result.success()) {
throw new PaymentFailedException(result.message());
}
order.pay();
repository.save(order);
publisher.publish(new OrderPaidEvent(orderId));
}
}应用层负责事务边界、用例编排,不写业务规则。
package infrastructure;
import domain.*;
public class AlipayGateway implements PaymentGateway {
@Override
public PaymentResult pay(String orderId, Money amount) {
// 调用支付宝 SDK,做签名、超时、重试
return new PaymentResult(true, "ok");
}
}package infrastructure;
import domain.OrderRepository;
public class JdbcOrderRepository implements OrderRepository {
@Override
public void save(Order order) {
// 写入数据库
}
@Override
public Order findById(String id) {
// 从数据库读取并重建领域对象
return null;
}
}替换支付渠道或存储时,只需新增实现类,领域层和应用层不变。
依赖倒置让核心逻辑可以脱离数据库和第三方接口进行单元测试:
@Test
void should_pay_order() {
var repo = new InMemoryOrderRepository();
var gateway = (orderId, amount) -> new PaymentResult(true, "ok");
var publisher = new RecordingPublisher();
var service = new OrderApplicationService(repo, gateway, publisher);
var order = new Order("o1", List.of(new OrderItem("p1", 1)));
repo.save(order);
service.pay("o1");
assertEquals(OrderStatus.PAID, repo.findById("o1").status());
assertTrue(publisher.hasEvent(OrderPaidEvent.class));
}演进方向:订单量增大后,可引入 CQRS 分离读写;支付渠道增多后,可抽象支付路由;跨服务协作时,领域事件可改为消息队列。这些演进都不需要推翻现有分层。
架构师的产出不是框架堆砌,而是清晰的边界和可解释的决策。以订单系统为例,分层 + 依赖倒置 + 领域事件,让系统在半年内可上线,又为未来替换支付、存储和拆分服务留出空间。架构的价值,在于让变化发生时,代价可控。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。