技术探索与实践:从“做出来”到“做得好”的成长之路

胡军
2025-06-23 05:54
阅读 262

在做开发的这些年里,我经历过项目顺利上线时的激动,也遭遇过凌晨三点还在服务器上排查问题的崩溃。而最让我有成就感的,不是某个功能实现了,而是在面对不确定和挑战时,我们是如何一步步把技术落地,并且真正用起来的。

这篇文章想结合我的一个实际项目经历,谈谈我在技术探索与实践中的一些思考和收获,希望能给正在路上或者刚起步的同学一些启发。


项目背景:一次“看似简单”的需求引发的技术重构

项目背景:一次“看似简单”的需求引发的技术重构

事情要从两年前的一个项目说起。当时公司要做一个新业务线的产品后台管理平台,核心是一个工单系统,负责用户提交请求、客服处理、状态流转等流程。

听起来是不是很熟悉?没错,就是那种“常规但又不简单的”后台系统。客户方希望能在两个月内上线第一版,并且后续还能持续扩展支持更多场景(比如审批流、权限体系、报表统计)。

一开始,团队按照经验选择了一个基于 Vue + Spring Boot 的技术栈,快速搭起了原型。但随着业务逻辑逐渐复杂,系统的可维护性和扩展性开始出现问题

  • 页面结构越来越臃肿,组件之间耦合严重
  • 后端接口频繁修改,数据模型变更后大量代码需要调整
  • 新人接手成本高,很多设计没有文档沉淀
  • 某些复杂查询响应时间超过5秒,影响用户体验

于是,我和团队决定启动一次技术上的重构计划,不再只是“做出东西”,而是在有限时间内“做好产品”。


遇到的挑战:技术方案如何选?怎么说服团队?

遇到的挑战:技术方案如何选?怎么说服团队?

最大的难点,其实不是写代码,而是统一认知确定方向

我们面临几个关键问题:

  1. 要不要引入TypeScript?
  2. 是否应该采用微服务架构?
  3. 前端架构如何拆分以降低维护成本?
  4. 性能优化该从哪下手?

每个选项背后都有其合理性,也有对应的代价。比如TypeScript能提高类型安全性,但也可能增加初期学习成本;微服务适合解耦系统,但当前业务体量未必适用。

这时候就需要回到业务本身去判断。

我们开了几次技术评审会,做了两个动作:

  • 画出业务核心路径(也就是用户最常用的功能点)
  • 评估每个技术方案对这些核心路径的影响

例如,在前端部分,我们发现大多数页面都围绕“工单生命周期”展开。所以我们决定尝试领域驱动设计+模块化前端架构,将“工单创建、处理、关闭”作为独立子模块进行封装。

而在后端,我们选择了领域建模+整洁架构的方式,把业务逻辑集中在Domain层,避免Controller中充斥着if/else判断和业务逻辑。


我们是怎么做的?技术和架构实践分享

我们是怎么做的?技术和架构实践分享

✅ 前端架构:抽离领域模型与模块封装

我们没有一开始就引入复杂的框架或微前端方案,而是先从页面结构入手,通过命名约定+目录划分来约束开发规范。

举个例子,我们将每个模块按如下方式组织:

modules/
├── order-management/
│   ├── components/
│   ├── pages/
│   ├── services/
│   └── store/

同时使用Vue Router + 动态加载机制,实现模块级别的懒加载。

对于状态管理,我们也做了改进,从早期的 Vuex 全局状态下沉为模块级的状态容器,这样每个模块都可以自己管理自己的状态,互不影响。

关键代码示例

在定义Store时,我们采用了命名空间:

// modules/order/store.js
export default {
  namespaced: true,
  state: () => ({
    orders: [],
    loading: false,
  }),
  mutations: {
    setOrders(state, data) {
      state.orders = data;
    },
    setLoading(state, status) {
      state.loading = status;
    }
  },
  actions: {
    async fetchOrders({ commit }) {
      commit('setLoading', true);
      const res = await get('/api/orders');
      commit('setOrders', res.data);
      commit('setLoading', false);
    }
  }
}

然后在入口文件统一注册:

// main.js
import { createApp } from 'vue';
import App from './App.vue';
import orderModule from './modules/order/store';

const app = createApp(App);

app.use(Vuex, {
  modules: {
    order: orderModule
  }
});

app.mount('#app');

这样的做法,让新人更容易理解项目结构,也让后续的迁移和替换更轻松。


✅ 后端架构:从MVC走向整洁架构与领域驱动

在后端方面,我们原来的做法是典型的Spring Boot MVC结构——Controller调Service,Service操作DAO。但随着字段变动频繁、业务判断复杂,越来越多的逻辑混杂在Service里。

于是我们决定尝试整洁架构(Clean Architecture),将核心业务逻辑从框架细节中剥离出来。

我们重新设计了架构层级:

Application Layer(应用层)
└── Use Case(用例层)
    └── Domain Entities(领域实体)
        └── Repository Interface(仓储接口)
            └── Infrastructure(基础设施层)

举个例子,针对“创建工单”这个操作,我们这样组织:

用例层

public class CreateOrderUseCase {
    
    private final OrderRepository repository;

    public CreateOrderUseCase(OrderRepository repository) {
        this.repository = repository;
    }

    public UUID execute(CreateOrderCommand command) {
        // 核心业务逻辑
        Order order = new Order(command.getTitle(), command.getContent());
        return repository.save(order);
    }
}

Controller 层

@RestController
@RequestMapping("/orders")
public class OrderController {

    private final CreateOrderUseCase useCase;

    public OrderController(CreateOrderUseCase useCase) {
        this.useCase = useCase;
    }

    @PostMapping
    public ResponseEntity<UUID> createOrder(@RequestBody CreateOrderRequest request) {
        UUID id = useCase.execute(new CreateOrderCommand(request.title(), request.content()));
        return ResponseEntity.ok(id);
    }
}

实现层(Infrastructure)

@Repository
public class JpaOrderRepository implements OrderRepository {

    private final OrderJpaRepository jpaRepository;

    public JpaOrderRepository(OrderJpaRepository jpaRepository) {
        this.jpaRepository = jpaRepository;
    }

    @Override
    public UUID save(Order order) {
        return jpaRepository.save(order.toEntity()).getId();
    }
}

虽然代码量变多了,但带来了极大的好处:

  • 业务逻辑集中且稳定
  • 可以方便地切换数据库实现(比如换成MongoDB)
  • 单元测试更容易模拟依赖项
  • 新人更容易理解业务边界

开发过程中踩过的坑和反思

在整个过程中,我们也踩了不少坑,总结下来几个教训特别值得分享。

❌ 太早引入复杂技术方案

有一段时间我们想一步到位,直接在前端引入Vue3+Vite+Pinia组合。结果是——打包异常慢,开发人员频繁卡顿,严重影响效率。最后我们还是退回到Vue2+Webpack方案,先把基础打牢。

教训:技术选型要服务于目标,而不是炫技

❌ 忽视文档和沟通成本

起初为了赶进度,很多设计决策都是口头达成一致,没及时记录。后来交接时才发现不同人对同一模块的理解完全不一样。

我们后来建立了两个制度:

  1. 架构决策记录(ADR):每次重要技术决策都要形成文档
  2. 模块负责人制:每个人负责一两个模块,确保有人知道“这东西到底咋运作”

❌ 过度设计导致进度失控

有一个模块我们试图搞出“通用的规则引擎”,结果折腾了两周都没落地上。最后砍掉重来,用配置化的JSON解决了同样问题。

建议:在业务初期,不要追求“未来可能会用到”,而要优先解决“现在必须完成的任务”


成果与收益:不仅仅是性能提升

经过这次重构之后,我们的项目质量有了明显改善:

指标 改造前 改造后
页面首次加载速度 4s+ 1.8s
接口平均响应时间 600ms 200ms
新人入职上手时间 约2周 5天左右
单元测试覆盖率 <10% 65%+

更重要的是,我们建立了清晰的工程规范和文档体系,使得后续迭代变得更加可控和高效。


给开发者的一些建议

如果你也在探索技术如何真正落地、并产生价值,这里有几个我觉得非常重要的建议:

🔧 技术选型要有业务视角

技术从来不是孤立存在的。一个好的技术选型,不是看它多先进,而是看它是否适配当前的业务阶段、团队能力和发展目标

📚 写好文档和注释真的有用

别相信“代码即文档”。好的注释和文档能节省你和别人几百个小时的调试时间。

💡 多问几个“为什么”,少写几行“看起来像样”的代码

技术探索的过程本质上是不断提问、验证、否定再重建的过程。有时候,花一个小时弄清楚一个问题的本质,比埋头写三天代码还管用。

🤝 和队友保持良好沟通,尤其是分歧的时候

不同意见不是坏事。如果大家都能站在对方的角度去理解彼此的选择,反而更容易达成共识,推动项目往前走。


结语:技术探索是一条长期主义的路

回顾整个项目的历程,我觉得最有意义的事情,不是最终用了什么技术栈,而是我们在面对问题时坚持了工程师的职业素养:理性分析、主动思考、敢于重构、持续优化

每一个技术方案的落地,都不是灵光一闪,而是一个又一个深夜思考、反复推敲后的结果。

我也希望你能在这条路上,越走越远,也能写出属于你自己的一套“技术方法论”。

如果你觉得这篇文章对你有所启发,欢迎留言交流,我们一起进步。技术探索的路上,你我不是独行者。

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝