Skip to content
【腾讯云】WorkBuddy 全场景 AI 办公工作台,团队旗舰版低至198元/月
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中
【腾讯云】智能体开发平台ADP,新客首月专属价,最高直降 880 元,构建、分发、治理企业级 Agent,一站式开启智能体生产力。
广告位招租
在此投放您的广告内容
联系我

开发规范与命名规范(建议) ​

提示信息

版本: 1.5 最后更新: 2024-03-12 适用对象: 开发工程师、技术负责人

统一的开发规范和命名规范有利团队协作,提高开发效率,减少错误,下边对日常开发做了简要的规范,供所有成员参考。

1. 数据库表和字段命名 ​

在 SQL Server 中,表名推荐使用下划线分隔的小写形式order_status_log,而非无分隔符的驼峰式orderstatuslog。 以下是具体分析:

1.1 推荐理由 ​

可读性更强

  • order_status_log 通过下划线明确分隔单词,便于快速识别字段含义(如 order、status、log),尤其适合长表名或团队协作场景。
  • orderstatuslog 无分隔符,需依赖命名习惯理解,可能增加阅读成本。

符合主流规范

  • 多数 SQL 规范(如 Google、Airbnb)建议使用 蛇形命名法(snake_case),即小写下划线分隔。
  • snake_case 是 SQL 社区事实标准( PostgreSQL/MySQL/Airbnb SQL 规范均如此),SQL Server 虽不区分大小写,但小写+下划线跨平台最稳。

避免潜在问题

  • 若未来扩展字段或关联其他表,order_status_log 更易扩展(如 order_status_log_detail )。
  • orderstatuslog 可能因命名模糊导致混淆(如是否包含 status或 log)。

1.2命名规范对比 ​

方案优点缺点适用场景
order_status_log清晰、易读,符合 SQL 社区习惯名称较长复杂业务表、团队协作
orderstatuslog简洁,适合简单场景可读性差,易混淆临时表、小型项目

1.3 其他注意事项 ​

大小写一致性

  • SQL Server 默认不区分大小写,但建议统一使用小写,避免跨平台问题(如 Linux 文件系统区分大小写)。

避免保留字 - 确保表名不与 SQL 关键字冲突(如 order是保留字,需用 [order]引用,但 order_status_log仍优于 orderstatuslog)。 - 但更好的实践是干脆别用 order 做前缀,用 sales_order_status_log 比 order_status_log 更安全。

业务前缀(可选)

  • 若系统包含多个模块,可添加短前缀(如 crm_order_status_log),前缀语义明确即可,但建议控制前缀长度。

1.4 示例场景 ​

sql
-- 推荐命名
-- 订单状态日志表
CREATE TABLE order_status_log (
  log_id INTPRIMARY KEY,
  order_id VARCHAR(32),
  status VARCHAR(20),
  change_time DATETIME
);
sql
-- 可读性较差,不推荐
-- 订单状态日志表
CREATE TABLE orderstatuslog (
  logid INTPRIMARY KEY,
  orderid VARCHAR(32),
  status VARCHAR(20),
  changetime DATETIME
);

1.5 总结 ​

优先选择 order_status_log,因其符合 SQL 社区规范、可读性高,且能适应长期维护需求。若项目已有特定命名规范(如强制驼峰式),则需与团队保持一致,即遵循「存量优先」原则。

2. API 控制器命名 ​

在 .NET6+ 的 API 项目中,控制器的命名需要遵循 RESTful 规范和 Clean Code 原则,以下是具体建议:

2.1 核心命名规范 ​

使用 PascalCase(大驼峰式)

  • 类名每个单词首字母大写,例如:CreditCardsController、OrdersController

复数形式表示资源集合

  • 控制器名称应使用复数名词,表示操作的资源集合,例如:
    • ProductsController(产品集合)
    • OrdersController(订单集合)
  • 避免单数形式,推荐 OrdersController 而非 OrderController,更符合 RESTful 资源集合的表达习惯。

避免动词,体现资源属性

  • 控制器名应直接映射业务资源,而非操作,例如:
    • ✅ CustomersController(客户资源)
    • ❌ CustomerController(模糊不清)
    • ❌ GetCustomersController(含动词)。

2.2 具体场景示例 ​

资源类型控制器命名路由示例说明
信用卡产品列表CreditCardProductsController/api/creditcardproducts管理信用卡产品(CRUD)
信用卡订单CreditCardOrdersController/api/creditcardorders处理订单创建、状态更新

2.3 命名禁忌与优化 ​

避免以下命名方式

  • 动词开头:如 GetOrdersController→ 应用 HTTP 动词(GET /api/orders)。
  • 缩写或模糊词汇:如 CustController→ 使用完整名称 CustomersController。
  • 混合层级:如 CreditCardOrderController→ 拆分为 CreditCardOrdersController和 CreditCardController。 一致性原则
  • 同一模块的控制器命名风格需统一,例如:
    • 若使用 Controller后缀,所有控制器均需添加(如 ProductsController)。
    • 若采用领域驱动命名(如 OrderService),需与业务逻辑层区分。

2.4 路由与控制器关联 ​

通过 [Route]特性定义路由,确保控制器名与路由路径匹配:

C#
[ApiController]
[Route("api/[controller]")]  // 路由自动解析为 /api/creditcardproducts
public class CreditCardProductsController : ControllerBase
{
    // 操作方法...
}

2.5 复杂场景的命名策略 ​

2.5.1 资源嵌套 ​

若资源存在层级关系,使用路径嵌套:

C#
[Route("api/customers/{customerId}/orders")]
public class CustomerOrdersController : ControllerBase
{
    // 客户订单相关操作...
}

2.5.2 版本控制 ​

API 版本可通过路由参数区分,控制器名无需包含版本号:

C#
[Route("api/v1/creditcardproducts")]
public class CreditCardProductsController : ControllerBase { }

优点:

  • 最直观,用户一眼知道用哪个版本
  • 缓存友好(不同 URL)
  • 兼容性好,所有 HTTP 客户端都支持
  • Swagger/OpenAPI 支持完善

缺点:

  • URL 会变(但可以接受,因为版本升级本来就是破坏性变更)

💡 提示信息

这是业界最主流的做法,Azure、GitHub、Stripe 都用这种方式。

也可以用Header实现,但不建议。

2.6 验证工具与测试 ​

Swagger 自动生成

  • 使用 [ApiExplorerSettings] 和 Swagger 配置,确保控制器名在文档中清晰展示。
  • 也可使用微软官方的 scalar ,类似Swagger。

单元测试命名

  • 建议测试类名与控制器名对应,例如:
C#
public class CreditCardProductsControllerTests {
    //.....
 }

2.7 总结 ​

最佳实践:

  • 使用 复数名词 + Controller 后缀(如 CreditCardProductsController )
  • 遵循 RESTful 路由规则(/api/{controller}/{id?})
  • 保持与业务领域一致,避免技术术语干扰可读性
  • 通过规范化的命名,可显著提升代码可维护性和团队协作效率。

3. Action 命名规则( C# 操作方法) ​

在 .NET 6+ 的 Web API 项目中,控制器 (Controller) 与操作方法 (Action) 的命名遵循“约定优于配置”的原则。以下是基于 RESTful 风格的主流建议,您可以根据项目规范进行调整。

3.1 使用 PascalCase 命名 ​

方法名应采用 PascalCase(每个单词首字母大写)格式,这是 C# 的通用命名规范。

C#
public class ProductsController : ControllerBase
{
public IActionResult GetAll() { }
public IActionResult GetById(int id) { }
}

3.2 语义化命名,而非“动词+控制器名” ​

应避免使用 GetUserController.GetUser 这类冗余的命名方式。更推荐的做法是,仅用 Get 表示获取操作,通过 HTTP 方法和路由来区分具体资源。 对于非CRUD的业务操作,推荐使用动词 + 名词的语义化命名(如 CalculateDiscount、ValidateUser),比单纯的 Get/Post 更具可读性。

C#
[HttpGet]
public IActionResult Get() { }
[HttpGet("{id}")]
public IActionResult Get(int id) { }
[HttpPost]
public IActionResult Create([FromBody] ProductDto dto) { }
[HttpPut("{id}")]
public IActionResult Update(int id, [FromBody] ProductDto dto) { }
[HttpDelete("{id}")]
public IActionResult Delete(int id) { }

3.3 通过特性明确 HTTP 方法 ​

每个 Action 方法都必须使用 [HttpGet], [HttpPost], [HttpPut], [HttpDelete]等特性来明确其支持的 HTTP 方法。不添加这些特性,框架将无法将请求正确路由到该方法。

C#
public class OrdersController : ControllerBase
{
// GET /orders
[HttpGet]
public IActionResult Get() { }
// POST /orders
[HttpPost]
public IActionResult Post([FromBody] OrderDto dto) { }
}

3.4 使用 [NonAction] 标记非 Action 方法 ​

如果控制器中存在一些辅助性的私有方法,不希望它们被暴露为 API 接口,应使用 [NonAction] 特性进行标记。

C#
public class UsersController : ControllerBase
{
[HttpGet("{id}")]
public IActionResult Get(int id) { }
// 此方法不会作为 API 接口暴露
[NonAction]
private string BuildCacheKey(int id) => $"user:{id}";
}

3.5 显式指定 Action 名称 ​

如果需要使用 RPC 风格的 URL(如 /api/products/GetProductById ),可以在 Action 上使用 [Route] 特性来显式指定路径。虽然此操作没有问题,但不符合 RESTful 风格,只要团队内统一规范,混合使用本身不是问题。

C#
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
// GET /api/products/GetProductById/1
[HttpGet("GetProductById/{id}")]
public IActionResult GetProductById(int id) { }
}

3.6总结 ​

类型规范示例
类名、实体名大驼峰 PascalCaseUserInfo
属性大驼峰 PascalCaseCreateTime
方法名大驼峰 PascalCaseGetUserList
方法参数小驼峰 camelCase,绝对不能用下划线,绝对不能用大驼峰userId
局部变量小驼峰 camelCase,第一个单词小写,后面单词首字母大写,不使用下划线,除了私有字段可以使用下划线,其他都不建议,甚至是不应该,这是.NET社区广泛采用的约定,能快速区分成员变量与局部变量。虽然微软官方说“可选”,但 Roslyn/StyleCop 默认推荐 _ 前缀。userList,private readonly ILogger _logger;private string _userName;
常量大驼峰 PascalCase

4.Vue3 前端命名 ​

在 Vue3 前端项目中,路由命名建议遵循 一致性、语义化、可维护性 原则,结合行业规范和实际业务场景,以下是具体建议和最佳实践:

4.1 核心命名规范 ​

4.1.1 路由名称( name 属性) ​

命名风格:使用 PascalCase(大驼峰式),与组件名保持一致

js
// 推荐
{ path: '/user', name: 'UserProfile', component: UserProfile }
// 不推荐
{ path: '/user', name: 'user_profile' }

唯一性:全局唯一,避免重复(可通过 ESLint 插件 eslint-plugin-vue-router 检查)

语义化:反映页面功能,如 OrderList 而非 Page1

4.1.2 路由路径( path 属性) ​

命名风格:使用 kebab-case(短横线分隔小写),符合 URL 标准\

js
// 推荐
path: '/user-profile/edit/:id'
// 不推荐
path: '/UserProfile/Edit/:id' 或 path: '/user_profile_edit/:id'// 动态参数:动态段使用 camelCase(小驼峰,JS 中访问更直观)
path: '/user/:userId/detail'// JS 中通过 params.userId 获取

4.1.3 嵌套路由与命名视图 ​

嵌套路由:父级路由名称建议包含模块名,子级路由体现层级关系

js
{
  path: '/system',
  name: 'System',
  children: [
    { path: 'user', name: 'SystemUser', component: SystemUser }
  ]
}

命名视图:通过 name 属性区分多视图区域(如顶部导航栏、侧边栏)

html
<router-viewname="sidebar"></router-view>
<router-viewname="main"></router-view>

4.2 目录结构与模块化 ​

4.2.1 路由配置拆分 ​

按功能模块拆分路由文件,提升可维护性

bash
src/
├── router/
│   ├── index.js          # 主路由入口
│   ├── static.js         # 静态路由(如登录页)
│   ├── dynamic.js        # 动态路由(需权限加载)
│   └── modules/
│       ├── user.js       # 用户模块路由
│       └── order.js      # 订单模块路由

4.2.2 组件与路由命名对应 ​

页面组件文件名与路由名称保持一致(PascalCase)

bash
src/
└── views/
    ├── UserProfile.vue   # 对应路由名称 UserProfile
    └── OrderDetail.vue   # 对应路由名称 OrderDetail---

4.3 最佳实践示例 ​

4.3.1 用户管理模块 ​

js
// router/modules/user.js
exportdefault [
  {
    path: '/user',
    name: 'UserList',
    component: () =>import('@/views/UserList.vue'),
    meta: { title: '用户列表' }
  },
  {
    path: '/user/:userId/detail',
    name: 'UserDetail',
    component: () =>import('@/views/UserDetail.vue'),
    meta: { title: '用户详情' }
  }
]

4.3.2 订单管理模块 ​

js
// router/modules/order.js
exportdefault [
  {
    path: '/order',
    name: 'OrderList',
    component: () =>import('@/views/OrderList.vue'),
    meta: { title: '订单列表' }
  },
  {
    path: '/order/:orderId/edit',
    name: 'OrderEdit',
    component: () =>import('@/views/OrderEdit.vue'),
    meta: { title: '编辑订单' }
  }
]

4.4 避坑指南 ​

4.4.1 常见错误 ​

  • 名称不匹配:路由名称与组件名不一致导致缓存失效(Vue3-Element-Admin 中需严格一致)
  • 动态参数混淆:路径参数使用下划线(如 :user_id)而非 camelCase,导致 JS 中访问困难
  • 重复命名:不同模块使用相同路由名称,引发跳转冲突

4.4.2 解决方案 ​

  • ESLint 约束:配置 vue-router/route-name-casing(PascalCase)和 vue-router/route-path-casing(kebab-case),从工具层面防止命名错误。
  • 模块前缀:中大型系统路由 name 添加模块前缀(如 UserList、OrderDetail),避免跨模块重名冲突。
  • 路由索引:在 docs/ 下维护简易路由映射表,记录路由用途与负责人,方便协作排查。

4.5 工具与配置建议 ​

ESLint 规则

js
// 前置:npm install -D eslint-plugin-vue-router,并在 plugins 里注册 'vue-router'。
// .eslintrc.js
rules: {
  'vue-router/route-name-casing': ['error', 'PascalCase'],
  'vue-router/route-path-casing': ['error', 'kebab-case'],
}

路由检查脚本

bash
# 路由检查脚本:检测重复 name
grep -rohE "name:\s*['\"][^'\"]+['\"]" "${1:-src/router}" | \
  sed -E "s/name:\s*['\"]([^'\"]+)['\"]/\1/" | sort | uniq -d

4.6 总结 ​

命名规范的核心目标是提升代码可读性和协作效率。

建议采用:

  • 路由名称:PascalCase(如 UserProfile)
  • 路由路径:kebab-case(如 /user-profile)
  • 动态参数:camelCase(如 :userId)

通过统一规范和工具约束,可显著降低维护成本,尤其适合中后台系统或大型项目。

5. 终极结论(建议背下来) ​

前端 Vue3 / JS:小驼峰 camelCase

  • userId userName createTime

后端 C#:大驼峰 PascalCase

  • UserId UserName CreateTime

数据库:小写 + 下划线

  • user_id user_name create_time

重点:它们本来就不需要一致!这是规范,不是错误!


为什么必须不一样?(行业标准)

  1. C# 官方规范:属性必须大驼峰
C#
public int UserId { get; set; } //强制
public string UserName { get; set; } //强制
public DateTime CreateTime { get; set; } //强制
  1. JS/TS/Vue 官方规范:变量必须小驼峰
js
const userId = 1 //强制
const userName = '张三' //强制
const createTime = '2025-06-01' //强制
  1. 数据库规范:必须小写 + 下划线
sql
user_id
user_name
create_time

这三者是三个不同的语言,各遵守各的规范!

就像:

  • 中文说 “你好”
  • 英文说 “hello”
  • 日文说 “こんにちは”

意思一样,写法不同,完全正常!

NOTE

那怎么通信?谁来转换? ASP.NET Core 会自动帮你转! 后端 C# 大驼峰 → 传给前端时 自动变成小驼峰

后端 C#:

C#
public class User
{
    public int UserId { get; set; }// 大驼峰
    public string UserName { get; set; }
}

前端收到的 JSON:

json

{
  "userId": 1,// 小驼峰
  "userName": "张三"
}

前端使用:

js
formData.userId = 1
formData.userName = "张三"

完整自动流转过程(一看就懂)

  1. 数据库(下划线)
user_id → user_name → create_time
  1. FreeSql 自动转 → C# 大驼峰
UserId → UserName → CreateTime
  1. .NET API 自动转 → JS 小驼峰
userId → userName → createTime
  1. 前端 Vue 只用小驼峰
formData.userId
formData.userName
formData.createTime

你最担心的问题:“前端和 C# 字段不一样,会不会对接失败?”

绝对不会!这是系统自动处理的!

  • 后端返回:UserId → 前端收到:userId
  • 前端提交:userId → 后端收到:UserId

全程自动,不需要你改任何代码!


你只需要记住这三句话

  1. Vue / JS 永远写小驼峰:userId
  2. C# 永远写大驼峰:UserId
  3. 数据库永远写下划线:user_id

最终给你的 “表单写法”(完全规范) Vue3 前端:

js
const formData = reactive({
  userId: '',
  userName: '',
  createTime: ''
})

C# 实体:

C#
public int UserId { get; set; }
public string UserName { get; set; }
public DateTime CreateTime { get; set; }

数据库:

sql
user_id, user_name, create_time

一句话总结:

  • 前端小驼峰,后端大驼峰,数据库下划线,三者自动转换,互不影响!
最近更新