介绍 CAF:Clean Architecture 前端

发布: (2026年2月21日 GMT+8 21:52)
5 分钟阅读
原文: Dev.to

Source: Dev.to

一次性编写业务逻辑。可在 React、Vue、Angular 或任何下一代框架中运行。CAF(Clean Architecture Frontend)是一个库,提供框架无关的核心,使相同的领域模型和用例通过替换适配器即可在任何前端运行。

前端应用常常把 UI、状态和业务规则混在一起。切换框架或需要在 React、Vue、Angular 之间共享逻辑时,通常要重写大量代码。Clean Architecture 能提供帮助,但要用单一的、框架无关的核心实现它并不容易。CAF 提供了这样的核心:原语和接口,使你的领域层和用例保持框架独立。

CAF 是一个用于构建遵循 Clean Architecture 的前端的框架无关核心。你只需实现一次领域层和应用层;React、Vue、Angular(以及未来的框架)通过小型适配器包接入。无需锁定在单一的 UI 技术栈。

In short

  • Framework‑agnostic – 一个核心;多种 UI。
  • Clean Architecture – 清晰的领域、应用和基础设施层。
  • Reactive primitives – 单一响应式引擎(Pulse)和用于表现层逻辑的 Ploc
  • Pluggable adapters – 路由、HTTP 和 UI 都是接口;由你(或生态系统)实现。
  • TypeScript‑first – 端到端的类型化 UseCaseRequestResultPloc

核心概念

Pulse

单个响应式值(如 ref)。用于单一状态(例如加载标志、当前用户)。

Ploc

展示逻辑组件 – 基于 Pulse 构建的有状态 bloc。持有 UI 相关的状态和方法。

UseCase

应用层的操作(命令或查询)。返回 RequestResult(loading、data、error),以便 UI 能显示加载/错误/成功。

RouteRepository

路由抽象。你的应用实现它(例如使用 React Router 或 Vue Router);RouteManager 使用它进行认证和导航。

领域层和应用层代码仅依赖这些抽象。基础设施(HTTP、路由、存储)以及 UI 层依赖于你的框架;核心层不依赖。

入门

1. 使用 CAFProvider 进行应用接线

// main.tsx or App.tsx
import { CAFProvider } from '@c-a-f/infrastructure-react';
import { setupUserPloc } from './caf/setup';

const userPloc = setupUserPloc();

export default function App() {
  return (
    <CAFProvider>
      {/* Your app UI goes here */}
    </CAFProvider>
  );
}

2. 在组件中使用 Ploc

import { usePlocFromContext, usePloc } from '@c-a-f/infrastructure-react';
import type { UserPloc } from '../caf/application';

export function UserList() {
  const ploc = usePlocFromContext('user');
  if (!ploc) return null;

  const [state] = usePloc(ploc);

  return (
    <div>
      {state.loading && <p>Loading...</p>}
      {state.error && <p>Error: {state.error}</p>}

      <button onClick={() => ploc.loadUsers()} disabled={state.loading}>
        Refresh
      </button>

      <ul>
        {state.users.map((u) => (
          <li key={u.id}>
            {u.name} – {u.email}
          </li>
        ))}
      </ul>
    </div>
  );
}

相同的 UserPloc 和用例可以驱动 Vue 或 Angular UI;仅需更换钩子(或组合函数/注入器)。

仓库结构

CAF 仓库是一个 monorepo,包含以下包:

  • Core@c-a-f/coreUseCasePlocPulseApiRequestRouteManager 以及共享接口。
  • Infrastructure(适配器)
    • @c-a-f/infrastructure-react – React hooks(usePlocuseUseCaseCAFProvideruseRouteManageruseRouteRepository)。
    • @c-a-f/infrastructure-vue – Vue 组合式函数和提供者。
    • @c-a-f/infrastructure-angular – Angular 服务和注入器。
  • 可选模块:验证(@c-a-f/validation)、工作流、权限、i18n、测试、devtools、CLI 脚手架等。

示例

  • example-react
  • example-vue
  • example-angular
  • example-vue-graphql
  • example-angular-websocket

每个示例都包含自己的 caf/ 文件夹(domain、application、infrastructure),可以直接复制到你的项目中。

目标受众

  • 团队 希望拥有单一的领域/应用层,并且能够灵活地使用 React、Vue 或 Angular。
  • 开发者 注重可测试性和清晰的边界(领域 vs. 应用 vs. 基础设施)。
  • 任何人 对框架特定的“Clean Architecture”配方感到厌倦,想要一个小型、共享的核心并遵循约定。

安装

npm install @c-a-f/core
npm install @c-a-f/infrastructure-react   # or -vue, -angular

可选:脚手架项目

npm install -g @c-a-f/cli
caf-init

然后创建一个 caf/ 文件夹,包含 domain/application/infrastructure/,并进行设置以连接仓库、用例和 Ploc。仓库中的文档和 README 会逐步演示确切的目录结构以及最小化的流程(例如,GetUsers 用例 → Ploc → React/Vue/Angular UI)。

链接

  • GitHub:
  • npm 组织:
  • 文档: (介绍, 包, 入门, 最佳实践, ADRs)
0 浏览
Back to Blog

相关文章

阅读更多 »

什么是域,它为何重要?

为什么领域很重要 作为一名软件工程师,我学到的最重要的事情之一是围绕领域设计系统。在软件设计方面…