当前位置: 首页 > news >正文

跨平台编码规范文档

1. 引言

1.1 目的与范围

本编码规范旨在为软件开发团队提供统一的代码编写标准,以提高代码质量、可维护性和团队协作效率。适用于使用C#、Java、安卓和Web前端(HTML/CSS/JavaScript/TypeScript)的项目开发,不针对特定语言特性,而是聚焦于通用的编程原则和最佳实践。

1.2 适用场景
  • 团队协作开发:确保代码风格一致性,降低理解成本。
  • 代码审查:作为评审依据,提升代码质量。
  • 项目交接:规范的代码结构便于后续维护和扩展。
  • 新人培训:帮助新成员快速融入团队开发流程。
1.3 参考标准

本规范参考了以下行业标准和最佳实践:

  • 通用原则:SOLID设计原则、DRY(Don’t Repeat Yourself)原则、KISS(Keep It Simple, Stupid)原则。
  • 语言特定规范
    • C#:Microsoft .NET编码规范
    • Java:Google Java Style Guide
    • 安卓:Android Code Style Guidelines
    • Web前端:Airbnb JavaScript Style Guide、Google HTML/CSS Style Guide
  • 安全标准:OWASP Top Ten、CWE/SANS Top 25。
1.4 规范优先级
  1. 强制性规则:必须严格遵守,违反可能导致安全风险、功能故障或严重影响代码可维护性。
  2. 推荐实践:建议遵循,有助于提升代码质量和可读性。
  3. 可选建议:根据项目需求和团队偏好选择实施。
1.5 版本控制

本规范将定期更新以适应技术发展和团队实践反馈。版本历史记录见附录X。团队成员应定期关注规范更新,并在新项目或迭代中应用最新标准。

2. 代码格式

2.1 缩进与空格
  • 统一缩进方式

    • 推荐使用4个空格进行缩进(避免使用Tab,防止不同编辑器显示差异)。
    • 例外:HTML/XML标签嵌套可使用2个空格以提高可读性。
  • 括号与空格

    • 函数/方法调用:括号前不加空格,如 functionName(param1, param2)
    • 条件语句:关键字与括号间留空格,如 if (condition) { ... }
    • 对象/数组字面量:键值对、元素间用逗号后加空格,如 const obj = { key: value, anotherKey: 123 };
  • 运算符空格

    • 二元运算符(如 +, -, =, ==, &&)两侧各留一个空格,如 x = a + b * c;
    • 一元运算符(如 !, ++, --)后不加空格,如 let y = !isValid;
2.2 行长度限制
  • 单行最大长度:建议不超过120个字符
  • 长表达式换行
    • 在运算符后换行,保持逻辑清晰。
    • 后续行缩进2级(8个空格),如:
      // Java示例  
      String longString = "This is a very long string that exceeds the line length limit " +  "so we break it into multiple lines for readability.";  
      
2.3 注释规范
  • 单行注释//):用于解释单行逻辑或临时注释代码。

    // 计算平均值  
    const avg = sum / count;  
    
  • 多行注释/* ... */):避免使用,改用连续单行注释。

    // 不推荐  
    /*  
    这是一段多行注释  
    描述函数的功能  
    */  // 推荐  
    // 这是一段多行注释  
    // 描述函数的功能  
    
  • 文档注释

    • C#/Java:使用 ///(C#)或 /** ... */(Java)生成API文档。
      /// <summary>  
      /// 计算两数之和  
      /// </summary>  
      /// <param name="a">第一个数</param>  
      /// <param name="b">第二个数</param>  
      /// <returns>两数之和</returns>  
      public int Add(int a, int b) { ... }  
      
    • Web前端:使用JSDoc/TSDoc规范。
      /**  * 计算两数之和  * @param {number} a - 第一个数  * @param {number} b - 第二个数  * @returns {number} 两数之和  */  
      function add(a, b) { ... }  
      
  • 注释原则

    • 解释为什么而非是什么,如:
      // 循环提前终止以避免性能问题(数据量超过1000时会导致OOM)  
      for (int i = 0; i < Math.min(items.size(), 1000); i++) { ... }  
      
    • 避免冗余注释:
      // 不推荐:注释重复代码逻辑  
      x = x + 1; // 增加x的值  // 推荐:解释业务含义  
      x = x + 1; // 更新计数器,触发下一页加载  
      
2.4 空行与分段
  • 逻辑分段:使用空行分隔不同功能块,如:

    public void processOrder(Order order) {  // 验证订单  if (order == null) {  throw new IllegalArgumentException("订单不能为空");  }  // 计算总价  double total = calculateTotal(order);  // 保存订单  saveOrder(order, total);  
    }  
    
  • 文件顶部留白:类/文件开头保留1个空行,如:

    import os  
    import sys  class MyClass:  ...  
    
  • 连续空行限制:不超过2个连续空行。

2.5 括号风格
  • K&R风格(推荐):左大括号与语句同行,右大括号独占一行。

    if (condition) {  // 代码块  
    } else {  // 代码块  
    }  
    
  • 例外情况

    • 单行方法/函数:可省略括号(需团队统一)。
      public int getCount() { return count; }  
      
2.6 对齐规则
  • 变量声明:无需强制对齐赋值符号,保持代码简洁。
    // 不推荐(过度对齐增加维护成本)  
    int         id       = 1;  
    string      name     = "John";  
    DateTime    birthday = DateTime.Now;  // 推荐  
    int id = 1;  
    string name = "John";  
    DateTime birthday = DateTime.Now;  
    
2.7 特殊字符使用
  • 行尾分号:必须使用(即使语言允许省略,如JavaScript)。
  • 字符串引号:统一使用单引号(')或双引号("),推荐:
    • Web前端:单引号用于HTML属性,双引号用于JavaScript字符串。
    • C#/Java:双引号用于字符串,单引号用于字符。

示例对比

不规范代码

function calculateTotal(items){let total=0;  
for(let i=0;i<items.length;i++){  
total+=items[i].price*items[i].quantity;}  
return total;}  

规范代码

/**  * 计算商品总价  * @param {Array<Object>} items - 商品列表  * @returns {number} 总价  */  
function calculateTotal(items) {  let total = 0;  for (let i = 0; i < items.length; i++) {  total += items[i].price * items[i].quantity;  }  return total;  
}  

3. 命名规范

3.1 标识符命名原则
  • 一致性原则:项目内保持统一的命名风格(如驼峰式、帕斯卡式、蛇形式)。
  • 可读性优先:使用完整单词或通用缩写,避免无意义字符(如 a, temp)。
  • 避免冗余:类名/接口名不包含类型后缀(如 UserModel, ProductService)。
3.2 命名风格约定
元素类型命名风格示例
变量小驼峰 (camelCase)userId, totalCount
常量全大写 + 下划线MAX_LENGTH, API_KEY
函数/方法小驼峰 (camelCase)getUserById(), calculateTotal()
类/接口大驼峰 (PascalCase)User, IEnumerable
命名空间/包小写 + 点分隔com.example.util, System.IO
文件/目录小写 + 连字符user-profile.js, components/layout
3.3 变量命名规范
  • 类型暗示:避免使用类型前缀(如 strName, intCount)。
  • 集合命名:使用复数或集合术语(如 users, productList)。
  • 布尔变量:使用 is/has/can 前缀(如 isValid, hasPermission)。

示例

// 不推荐
String sName = "John";
ArrayList<Integer> list = new ArrayList<>();
boolean valid = true;// 推荐
String name = "John";
List<Integer> scores = new ArrayList<>();
boolean isValid = true;
3.4 函数/方法命名规范
  • 动宾结构:明确表达功能(如 saveUser(), validateInput())。
  • 查询方法:使用 get/is/has 前缀(如 getUser(), isEmpty())。
  • 修改方法:使用 set/update/add/remove 前缀(如 setName(), removeItem())。

示例

// 不推荐
function process(x) { /* ... */ }
function data() { return users; }// 推荐
function calculateTax(amount) { /* ... */ }
function getUsers() { return users; }
3.5 类/接口命名规范
  • 名词/形容词:避免动词(如 User, Configuration, ReadOnlyCollection)。
  • 接口命名:推荐使用 I 前缀(如 IEnumerable, IValidator)。

示例

// 不推荐
class ProcessOrder { /* ... */ }
interface Validatable { /* ... */ }// 推荐
class OrderProcessor { /* ... */ }
interface IValidator { bool Validate(); }
3.6 命名空间/模块命名规范
  • 领域分层:按业务领域或功能模块划分(如 com.example.auth, app/services)。
  • 避免泛型名称:不使用 utils, helpers 等模糊命名。
3.7 缩写与简写规范
  • 使用公认缩写:如 id(标识符)、num(数字)、avg(平均值)。
  • 避免自创缩写:如 nbr(number)、msg(message)应使用完整形式。
3.8 测试相关命名
  • 测试类:使用 [被测试类]Test 命名(如 UserServiceTest)。
  • 测试方法:使用 [测试场景]_[预期行为] 模式(如 whenInputIsEmpty_throwException())。

示例

public class CalculatorTest {@Testpublic void givenTwoNumbers_whenAdded_returnsSum() {// 测试逻辑}
}
3.9 避免的命名陷阱
  • 保留字冲突:不使用语言保留字(如 class, function, null)。
  • 视觉相似字符:避免使用 l(小写L)、I(大写i)、O(大写o)作为单字符变量。
  • 文化敏感词汇:避免使用可能引起歧义的词汇(如 master/slave 可用 primary/replica 替代)。

命名检查清单

  1. 能否通过名称清晰理解功能?
  2. 是否符合团队统一的命名风格?
  3. 是否包含不必要的类型信息?
  4. 是否使用了有歧义的缩写或简写?
  5. 是否与现有命名模式一致?

4. 代码结构

4.1 文件组织与目录结构
  • 按领域/功能划分

    • 避免按技术类型分类(如 controllers/, services/),推荐按业务领域组织(如 user/, order/, payment/)。
    • 示例
      src/  
      ├── user/  
      │   ├── UserModel.cs  
      │   ├── UserController.js  
      │   ├── UserService.java  
      │   └── tests/  
      ├── order/  
      │   ├── OrderEntity.ts  
      │   ├── OrderRepository.kt  
      │   └── OrderApi.vue  
      └── shared/  ├── utils/  ├── constants/  └── exceptions/  
      
  • 避免深层嵌套:目录层级不超过4层,超过时应重构为模块。

4.2 模块化设计原则
  • 单一职责:每个模块/类/函数仅负责一个明确的功能。

  • 高内聚低耦合

    • 内聚性:模块内部元素关联紧密(如 UserService 专注用户业务逻辑)。
    • 耦合度:模块间依赖明确且可控(通过接口而非具体实现交互)。
  • 依赖倒置原则

    • 高层模块不依赖低层模块,二者依赖抽象接口。
    • 示例
      // 不推荐:高层依赖具体实现  
      class OrderService {  private MySQLUserRepository userRepo = new MySQLUserRepository();  
      }  // 推荐:依赖抽象接口  
      class OrderService {  private IUserRepository userRepo;  public OrderService(IUserRepository repo) { this.userRepo = repo; }  
      }  
      
4.3 组件/类设计规范
  • 类大小限制:单个类代码不超过500行(特殊情况需评审)。
  • 构造函数简洁性:参数不超过5个,复杂初始化使用Builder模式。
  • 方法长度限制:单个方法不超过30行,避免过长逻辑链。
4.4 分层架构
  • 典型分层(适用于后端/前端):

    1. 表示层(UI/API):处理用户交互和HTTP请求。
    2. 应用层:协调业务流程,不包含核心业务逻辑。
    3. 领域层:核心业务逻辑、实体和值对象。
    4. 基础设施层:数据访问、外部服务调用等。

    示例(Java后端):

    // 表示层  
    @RestController  
    public class UserController {  private final UserService userService;  public UserController(UserService service) { this.userService = service; }  @PostMapping("/users")  public ResponseEntity<UserDTO> createUser(@RequestBody UserDTO dto) {  return ResponseEntity.ok(userService.createUser(dto));  }  
    }  // 应用层  
    @Service  
    public class UserService {  private final UserDomainService domainService;  public UserService(UserDomainService service) { this.domainService = service; }  public UserDTO createUser(UserDTO dto) {  User user = domainService.registerUser(dto.getName(), dto.getEmail());  return mapToDTO(user);  }  
    }  // 领域层  
    @DomainService  
    public class UserDomainService {  public User registerUser(String name, String email) {  // 核心业务逻辑:验证邮箱、生成ID、创建用户  if (!EmailValidator.isValid(email)) {  throw new InvalidEmailException(email);  }  return new User(UUID.randomUUID(), name, email);  }  
    }  
    
4.5 前端组件结构
  • 组件职责分离

    • 容器组件:负责数据获取和状态管理。
    • 展示组件:专注UI渲染,无业务逻辑。

    示例(React):

    // 容器组件(UserListContainer.jsx)  
    const UserListContainer = () => {  const [users, setUsers] = useState([]);  useEffect(() => {  fetchUsers().then(data => setUsers(data));  }, []);  return <UserList users={users} onDelete={deleteUser} />;  
    };  // 展示组件(UserList.jsx)  
    const UserList = ({ users, onDelete }) => (  <div>  {users.map(user => (  <UserItem key={user.id} user={user} onDelete={onDelete} />  ))}  </div>  
    );  
    
4.6 依赖管理规范
  • 显式依赖声明

    • 使用包管理工具(npm, Maven, NuGet等)明确声明依赖版本。
    • 避免全局依赖(如全局安装的工具库)。
  • 版本控制

    • 使用语义化版本(SemVer),锁定次要版本(如 ^1.2.3)。
    • 定期更新依赖(至少每季度一次),使用工具(如Dependabot)自动检测安全漏洞。
4.7 配置管理
  • 环境分离:配置文件按环境区分(如 config/dev.properties, config/prod.json)。

  • 敏感信息:不硬编码密钥、数据库连接串等,使用环境变量或加密存储。

    示例(Node.js):

    // 不推荐  
    const dbConfig = {  host: "localhost",  password: "mysecretpassword"  
    };  // 推荐  
    const dbConfig = {  host: process.env.DB_HOST || "localhost",  password: process.env.DB_PASSWORD  
    };  
    
4.8 代码复用策略
  • 避免复制粘贴:提取公共逻辑为工具类、组件或库。

  • 组合优于继承:优先使用接口组合而非类继承,减少耦合。

    示例(Python):

    # 不推荐:继承导致紧耦合  
    class Bird:  def fly(self): pass  class Penguin(Bird):  def fly(self): raise NotImplementedError()  # 推荐:接口组合  
    class Flyable:  def fly(self): pass  class Bird:  def __init__(self, movement: Flyable = None):  self.movement = movement  class Penguin(Bird):  def __init__(self):  super().__init__(movement=None)  
    

代码结构检查清单

  1. 是否遵循单一职责原则?
  2. 依赖关系是否清晰且符合依赖倒置原则?
  3. 目录结构是否反映业务领域而非技术实现?
  4. 组件/类大小是否可控?
  5. 配置与敏感信息是否妥善管理?

5. 控制结构

5.1 条件语句规范
  • 简化布尔表达式:避免冗余的 == true== false

    // 不推荐  
    if (isValid == true) { ... }  
    if (hasPermission == false) { ... }  // 推荐  
    if (isValid) { ... }  
    if (!hasPermission) { ... }  
    
  • 卫语句优先:提前处理异常情况,减少嵌套。

    // 不推荐  
    public void processOrder(Order order) {  if (order != null) {  if (order.isPaid()) {  if (order.getItems().size() > 0) {  // 主逻辑  } else {  throw new InvalidOrderException("订单不能为空");  }  } else {  throw new PaymentRequiredException();  }  } else {  throw new IllegalArgumentException("订单不能为空");  }  
    }  // 推荐  
    public void processOrder(Order order) {  if (order == null) throw new IllegalArgumentException("订单不能为空");  if (!order.isPaid()) throw new PaymentRequiredException();  if (order.getItems().isEmpty()) throw new InvalidOrderException("订单不能为空");  // 主逻辑(无嵌套)  
    }  
    
  • 三元运算符限制:仅用于简单条件赋值,避免复杂逻辑。

    // 推荐  
    string status = isActive ? "Active" : "Inactive";  // 不推荐  
    var result = x > 10 ? (y < 5 ? "A" : "B") : (z != 0 ? "C" : "D");  
    
5.2 循环语句规范
  • 优先使用高级抽象:使用 forEach, map, filter 等替代原始 for 循环(支持时)。

    // 不推荐  
    const users = [];  
    for (let i = 0; i < data.length; i++) {  if (data[i].isActive) {  users.push(data[i]);  }  
    }  // 推荐  
    const users = data.filter(item => item.isActive);  
    
  • 避免无限循环:确保循环条件可终止,使用超时机制(如网络请求)。

    # 危险示例  
    while True:  result = fetch_data()  # 若请求失败可能导致死循环  process(result)  # 推荐  
    max_attempts = 3  
    for attempt in range(max_attempts):  try:  result = fetch_data()  process(result)  break  except Exception as e:  if attempt == max_attempts - 1:  raise  time.sleep(1)  # 重试间隔  
    
  • 循环变量作用域:避免循环变量泄露(如JavaScript中的 var)。

    // 不推荐(var作用域问题)  
    for (var i = 0; i < 10; i++) {  setTimeout(() => console.log(i), 100);  // 全部输出10  
    }  // 推荐(let块级作用域)  
    for (let i = 0; i < 10; i++) {  setTimeout(() => console.log(i), 100);  // 输出0-9  
    }  
    
5.3 Switch/Case 规范
  • 默认分支:必须包含 default 分支(即使为空)。

  • 贯穿行为:明确标注 fallthrough (如Java中使用注释)。

    switch (status) {  case ACTIVE:  processActive();  // fallthrough  case PENDING:  processPending();  break;  default:  // 处理未知状态  throw new IllegalArgumentException("未知状态: " + status);  
    }  
    
  • 避免复杂逻辑:每个 case 逻辑不超过10行,复杂逻辑提取为方法。

5.4 异常处理规范
  • 具体异常捕获:避免捕获通用异常(如 Exception),优先处理特定异常。

    // 不推荐  
    try {  file.Open();  
    } catch (Exception ex) {  Logger.Log(ex.Message);  // 可能掩盖真正问题  
    }  // 推荐  
    try {  file.Open();  
    } catch (FileNotFoundException ex) {  Logger.Log("文件不存在: " + ex.Path);  
    } catch (UnauthorizedAccessException ex) {  Logger.Log("无访问权限: " + ex.Message);  
    }  
    
  • 异常传播:底层组件抛出异常,高层组件处理。

    def read_config(file_path):  if not os.path.exists(file_path):  raise FileNotFoundError(f"配置文件不存在: {file_path}")  # 抛出异常  # ...  def main():  try:  config = read_config("app.conf")  except FileNotFoundError as e:  print(f"启动失败: {e}")  # 高层处理  sys.exit(1)  
    
  • 资源管理:使用 using(C#)、try-with-resources(Java)或 with(Python)确保资源释放。

    // Java示例  
    try (BufferedReader reader = new BufferedReader(new FileReader("data.txt"))) {  return reader.lines().collect(Collectors.joining());  
    } // 自动关闭reader  
    
5.5 空值处理规范
  • 防御性编程:检查参数和返回值是否为 null/None

    // 不推荐  
    function calculateTotal(orders: Order[]): number {  return orders.reduce((sum, order) => sum + order.amount, 0);  // 若orders为null会报错  
    }  // 推荐  
    function calculateTotal(orders: Order[] | null): number {  if (!orders) return 0;  return orders.reduce((sum, order) => sum + order.amount, 0);  
    }  
    
  • 空对象模式:使用空对象替代 null 返回值(如 Optional.empty() in Java)。

    // 推荐  
    public Optional<User> getUserById(String id) {  User user = userRepository.findById(id);  return user != null ? Optional.of(user) : Optional.empty();  
    }  // 使用  
    userService.getUserById("123")  .ifPresent(user -> process(user));  
    
5.6 控制结构复杂度限制
  • 圈复杂度(Cyclomatic Complexity):单个方法圈复杂度不超过10。
    • 使用工具(如SonarQube, ESLint)检测并重构复杂逻辑。
  • 嵌套层级:条件/循环嵌套不超过3层,超过时应提取方法。

控制结构最佳实践总结

  1. 保持代码扁平:减少嵌套,优先使用卫语句。
  2. 抽象替代复杂条件:将复杂条件逻辑提取为布尔方法。
  3. 异常处理策略
    • 抛出明确异常,避免捕获通用异常。
    • 资源管理使用语言提供的自动释放机制。
  4. 空值安全
    • 使用语言特性(如 Optional, ?? 操作符)处理空值。
    • 避免 null 作为方法返回值(优先返回空集合或空对象)。

6. 面向对象原则

6.1 类设计原则
  • 单一职责原则(SRP):每个类只负责一个明确的功能。

    // 不推荐:UserManager承担多个职责  
    class UserManager {  public void createUser(String name, String email) { /* 创建用户 */ }  public void sendWelcomeEmail(String email) { /* 发送邮件 */ }  public void generateReport() { /* 生成报表 */ }  
    }  // 推荐:职责分离  
    class UserService {  public void createUser(String name, String email) { /* 创建用户 */ }  
    }  class EmailService {  public void sendWelcomeEmail(String email) { /* 发送邮件 */ }  
    }  class ReportGenerator {  public void generateReport() { /* 生成报表 */ }  
    }  
    
  • 开闭原则(OCP):对扩展开放,对修改关闭。

    • 使用接口/抽象类定义行为,通过实现类扩展功能。
    // 基类  
    public abstract class DiscountStrategy {  public abstract decimal CalculateDiscount(Order order);  
    }  // 具体实现  
    public class ChristmasDiscount : DiscountStrategy {  public override decimal CalculateDiscount(Order order) {  return order.Total * 0.2m;  }  
    }  // 使用策略  
    public class OrderProcessor {  private readonly DiscountStrategy _strategy;  public OrderProcessor(DiscountStrategy strategy) { _strategy = strategy; }  
    }  
    
6.2 继承与组合
  • 组合优先:通过组合实现代码复用,减少继承层级。

    # 不推荐:多层继承导致耦合  
    class Animal:  def move(self): pass  class Bird(Animal):  def fly(self): pass  class Penguin(Bird):  def fly(self): raise NotImplementedError()  # 推荐:组合替代继承  
    class FlyBehavior:  def fly(self): pass  class Animal:  def __init__(self, movement):  self.movement = movement  class Penguin(Animal):  def __init__(self):  super().__init__(movement=None)  # 企鹅不会飞  
    
  • 继承规范

    • 子类必须完全理解父类行为(里氏替换原则)。
    • 避免修改父类非抽象方法的行为(除非明确允许)。
6.3 接口设计规范
  • 单一职责:接口只定义一组相关行为。

    // 不推荐:大而全的接口  
    interface UserService {  void createUser(String name);  void validateEmail(String email);  void sendNotification(String message);  
    }  // 推荐:拆分为多个小接口  
    interface UserManagement {  void createUser(String name);  
    }  interface EmailValidator {  boolean validateEmail(String email);  
    }  interface NotificationSender {  void sendNotification(String message);  
    }  
    
  • 最小接口原则:不强迫实现类依赖不需要的方法(ISP原则)。

6.4 抽象类 vs 接口
  • 抽象类:定义部分实现,用于代码复用(如模板方法模式)。
  • 接口:定义纯行为契约,支持多重实现。
6.5 设计模式应用
  • 常用模式
    • 工厂模式:创建对象时隐藏具体实现逻辑。

      class ProductFactory {  static createProduct(type) {  if (type === "A") return new ProductA();  if (type === "B") return new ProductB();  throw new Error("未知产品类型");  }  
      }  
      
    • 单例模式:确保类只有一个实例。

      public sealed class AppConfig {  private static readonly Lazy<AppConfig> _instance =  new Lazy<AppConfig>(() => new AppConfig());  public static AppConfig Instance => _instance.Value;  private AppConfig() { }  // 私有构造函数  
      }  
      
    • 观察者模式:对象间一对多依赖,当一个对象状态变化时通知所有依赖者。

      interface Observer {  void update(String message);  
      }  class Subject {  private List<Observer> observers = new ArrayList<>();  public void addObserver(Observer observer) {  observers.add(observer);  }  public void notifyObservers(String message) {  observers.forEach(o => o.update(message));  }  
      }  
      
6.6 数据封装
  • 访问控制
    • 字段设为私有(private),通过公共方法(getter/setter)访问。
    • 避免暴露内部数据结构(如返回集合的直接引用)。
    // 不推荐  
    public class User {  public List<String> roles;  // 直接暴露字段  
    }  // 推荐  
    public class User {  private List<String> roles = new ArrayList<>();  public List<String> getRoles() {  return Collections.unmodifiableList(roles);  // 返回不可变视图  }  public void addRole(String role) {  this.roles.add(role);  }  
    }  
    
6.7 依赖注入(DI)
  • 构造函数注入:优先通过构造函数提供依赖。

    class OrderService {  constructor(private paymentGateway: PaymentGateway) {}  public processOrder(order: Order) {  this.paymentGateway.charge(order.total);  }  
    }  
    
  • 避免静态依赖:不直接调用静态方法,通过接口注入。

面向对象设计检查清单

  1. 每个类是否只负责一个明确的职责?
  2. 继承关系是否符合里氏替换原则?
  3. 接口是否足够小且内聚?
  4. 是否过度使用继承而非组合?
  5. 依赖关系是否通过接口注入而非硬编码?

7. 安全性

7.1 输入验证
  • 所有外部输入必须验证:包括用户输入、API参数、文件上传等。

    // 不推荐:未验证输入  
    public void createUser(String email) {  User user = new User(email);  userRepository.save(user);  
    }  // 推荐:验证邮箱格式  
    public void createUser(String email) {  if (!EmailValidator.isValid(email)) {  throw new IllegalArgumentException("无效邮箱: " + email);  }  User user = new User(email);  userRepository.save(user);  
    }  
    
  • 验证策略

    • 白名单优先:允许已知合法值,拒绝其他所有输入。
    • 最小权限原则:限制输入长度、类型和范围。
7.2 防止SQL注入
  • 使用参数化查询:避免直接拼接SQL语句。

    # 不推荐(SQL注入风险)  
    query = f"SELECT * FROM users WHERE username = '{username}'"  
    cursor.execute(query)  # 推荐  
    query = "SELECT * FROM users WHERE username = %s"  
    cursor.execute(query, (username,))  
    
  • ORM框架:优先使用ORM(如Entity Framework, Hibernate),自动处理参数化。

7.3 防止跨站脚本攻击(XSS)
  • 输出编码:对所有用户生成的内容进行HTML/JavaScript编码。

    // 前端示例:使用DOMPurify净化HTML  
    const cleanHtml = DOMPurify.sanitize(userInput);  
    document.getElementById('output').innerHTML = cleanHtml;  
    
  • CSP(内容安全策略):限制页面可加载的资源来源。

    Content-Security-Policy: default-src 'self'; script-src 'self' 'trusted-scripts.example.com';  
    
7.4 防止跨站请求伪造(CSRF)
  • CSRF令牌:为敏感操作(如表单提交)生成并验证令牌。
    // Java Spring示例  
    @PostMapping("/transfer")  
    public String transferFunds(@RequestParam String amount,  @RequestParam String recipient,  @RequestParam("_csrf") String csrfToken) {  // 验证CSRF令牌  csrfTokenValidator.validate(csrfToken);  // 处理转账  
    }  
    
7.5 密码安全
  • 哈希存储:使用强哈希算法(如BCrypt、Argon2)存储密码。

    // .NET示例  
    string hashedPassword = BCrypt.Net.BCrypt.HashPassword(plainPassword);  // 验证密码  
    bool isCorrect = BCrypt.Net.BCrypt.Verify(plainPassword, hashedPassword);  
    
  • 密码策略

    • 最小长度:至少12个字符。
    • 复杂度:包含大小写字母、数字和特殊字符。
    • 定期更换:每90天强制重置密码。
7.6 敏感数据处理
  • 数据脱敏:不显示完整敏感信息(如信用卡号、身份证号)。

    // 示例:显示部分信用卡号  
    public String maskCardNumber(String cardNumber) {  if (cardNumber == null || cardNumber.length() <= 4) {  return cardNumber;  }  return "****-****-****-" + cardNumber.substring(cardNumber.length() - 4);  
    }  
    
  • 数据传输:所有敏感数据通过HTTPS传输,禁用明文协议。

7.7 权限控制
  • 基于角色的访问控制(RBAC)

    # 示例:检查用户是否有管理员权限  
    def deleteUser(userId, currentUser):  if not currentUser.hasRole("ADMIN"):  raise PermissionDeniedException("需要管理员权限");  userRepository.delete(userId);  
    
  • 最小权限原则:用户仅拥有完成任务所需的最低权限。

7.8 错误处理与日志安全
  • 错误信息:不向客户端暴露堆栈跟踪或内部路径。

    // 不推荐  
    app.get('/user', (req, res) => {  try {  // 业务逻辑  } catch (err) {  res.status(500).send(err.stack);  // 暴露敏感信息  }  
    });  // 推荐  
    app.get('/user', (req, res) => {  try {  // 业务逻辑  } catch (err) {  logger.error("获取用户失败", err);  res.status(500).send("服务器内部错误");  // 通用错误信息  }  
    });  
    
  • 日志安全

    • 敏感信息(如密码、令牌)不记录。
    • 日志文件访问控制严格。
7.9 安全漏洞扫描
  • 定期扫描:使用工具(如OWASP ZAP、Nessus)进行漏洞扫描。
  • 依赖检查:定期检查第三方库安全漏洞(如OWASP Dependency-Check)。

安全检查清单

  1. 是否验证了所有外部输入?
  2. 是否使用了参数化查询或ORM?
  3. 是否对用户生成内容进行了输出编码?
  4. 是否实现了CSRF防护?
  5. 是否安全存储和处理密码?
  6. 是否限制了敏感数据的访问和显示?
  7. 是否实现了细粒度的权限控制?
  8. 是否避免向客户端暴露敏感错误信息?

8. 性能优化

8.1 避免资源泄漏
  • 及时释放资源:使用 using(C#)、try-with-resources(Java)或 with(Python)确保资源关闭。

    // 不推荐:手动关闭可能遗漏  
    public void readFile(String path) throws IOException {  FileInputStream fis = new FileInputStream(path);  try {  // 使用fis读取文件  } finally {  fis.close();  // 必须在finally中关闭  }  
    }  // 推荐:自动关闭资源  
    public void readFile(String path) throws IOException {  try (FileInputStream fis = new FileInputStream(path)) {  // 使用fis读取文件  } // 自动关闭  
    }  
    
  • 数据库连接池:使用连接池管理数据库连接,避免频繁创建和销毁。

8.2 内存管理最佳实践
  • 避免内存泄漏

    • 静态集合中不保存长生命周期对象的引用。
    • 及时解除监听器和回调引用。
  • 大对象处理

    • 避免在循环中创建大对象(如大型数组)。
    • 优先使用对象池复用重量级对象(如线程、数据库连接)。
8.3 算法复杂度优化
  • 避免O(n²)算法:优先使用O(n)或O(log n)算法。
    // 不推荐:双重循环(O(n²))  
    function findDuplicates(arr) {  const duplicates = [];  for (let i = 0; i < arr.length; i++) {  for (let j = i + 1; j < arr.length; j++) {  if (arr[i] === arr[j]) {  duplicates.push(arr[i]);  }  }  }  return duplicates;  
    }  // 推荐:使用Set(O(n))  
    function findDuplicates(arr) {  const seen = new Set();  const duplicates = new Set();  for (const item of arr) {  if (seen.has(item)) {  duplicates.add(item);  } else {  seen.add(item);  }  }  return Array.from(duplicates);  
    }  
    
8.4 异步与并发处理
  • 异步操作:I/O密集型任务使用异步编程提高吞吐量。

    // C#示例:异步文件读取  
    public async Task<string> ReadFileAsync(string path) {  using (var reader = File.OpenText(path)) {  return await reader.ReadToEndAsync();  }  
    }  
    
  • 线程池使用:计算密集型任务使用线程池避免创建过多线程。

    // Java示例:使用ExecutorService  
    ExecutorService executor = Executors.newFixedThreadPool(10);  
    Future<String> future = executor.submit(() -> {  // 执行耗时任务  return "结果";  
    });  
    
  • 锁粒度控制:避免大范围同步,减小锁的作用域。

    # 不推荐:粗粒度锁  
    lock = threading.Lock()  def process_data():  with lock:  # 长时间操作(如网络请求)  data = fetch_data()  # 实际需要同步的操作  shared_resource.append(data)  # 推荐:细粒度锁  
    def process_data():  data = fetch_data()  # 非同步操作  with lock:  shared_resource.append(data)  # 仅同步关键操作  
    
8.5 缓存策略
  • 本地缓存:使用 ConcurrentHashMap(Java)或 MemoryCache(.NET)缓存高频访问数据。

    private static final ConcurrentHashMap<String, User> userCache = new ConcurrentHashMap<>();  public User getUser(String id) {  return userCache.computeIfAbsent(id, this::fetchUserFromDb);  
    }  
    
  • 分布式缓存:使用Redis、Memcached缓存跨实例数据。

8.6 懒加载与预加载
  • 懒加载:延迟初始化对象,直到首次使用。

    class Config {  constructor() {  this._settings = null;  }  get settings() {  if (!this._settings) {  this._settings = this.loadSettings(); // 首次访问时加载  }  return this._settings;  }  
    }  
    
  • 预加载:适用于已知后续会使用的数据(如启动时加载配置)。

8.7 数据库查询优化
  • 索引优化:为高频查询字段添加索引。

  • 批量操作:避免循环执行单条SQL,使用批量插入/更新。

    // JDBC批量插入示例  
    try (Connection conn = dataSource.getConnection();  PreparedStatement pstmt = conn.prepareStatement("INSERT INTO users (name, email) VALUES (?, ?)")) {  for (User user : users) {  pstmt.setString(1, user.getName());  pstmt.setString(2, user.getEmail());  pstmt.addBatch();  }  pstmt.executeBatch();  
    }  
    
  • 避免N+1查询:使用JOIN或批量查询替代循环查询。

性能检查清单

  1. 是否存在资源未及时释放的情况?
  2. 是否有内存泄漏风险(如静态集合持有对象引用)?
  3. 是否使用了高效的算法和数据结构?
  4. 是否将I/O密集型操作转为异步处理?
  5. 是否合理控制了锁的粒度?
  6. 是否对高频访问数据使用了缓存?
  7. 是否优化了数据库查询(索引、批量操作等)?

9. 测试与调试

9.1 单元测试原则
  • 单一职责:每个测试方法只验证一个功能点或业务逻辑。

    # 不推荐:一个测试方法验证多个功能
    def test_user_creation_and_login():user = create_user("testuser", "test@example.com")assert user is not Noneresult = login(user.username, "password")assert result == "success"# 推荐:拆分测试
    def test_user_creation():user = create_user("testuser", "test@example.com")assert user is not Nonedef test_user_login():user = create_user("testuser", "test@example.com")result = login(user.username, "password")assert result == "success"
    
  • 独立运行:测试方法之间不能有依赖关系,每次运行都应独立执行。

  • 可重复性:相同的输入应始终产生相同的输出,避免依赖外部可变状态(如实时时间、随机数)。

9.2 测试覆盖率
  • 目标覆盖率:核心业务代码覆盖率应达到80%以上,非核心代码可适当降低。
  • 覆盖范围
    • 分支覆盖:确保所有 ifswitch 等条件分支都被测试。
    • 异常覆盖:验证方法抛出的所有异常情况。
    • 边界条件覆盖:测试输入的最小值、最大值、空值等边界情况。
9.3 测试命名规范
  • 清晰描述:测试方法名应明确表达测试内容和预期结果。
    // 推荐
    @Test
    public void whenUserExists_loginShouldSucceed() {// 测试逻辑
    }@Test
    public void whenEmailIsInvalid_createUserShouldThrowException() {// 测试逻辑
    }
    
9.4 调试信息与日志记录
  • 日志级别:使用分级日志(DEBUG、INFO、WARN、ERROR)控制输出内容。

    const winston = require('winston');
    const logger = winston.createLogger({level: 'info',format: winston.format.json(),transports: [new winston.transport.Console()]
    });logger.debug('Debug信息,仅在开发环境使用');
    logger.info('正常业务信息');
    logger.warn('潜在问题警告');
    logger.error('错误信息');
    
  • 调试输出

    • 避免在生产环境中保留调试语句(如 console.log)。
    • 使用日志记录代替 console.log,并通过配置文件控制日志输出。
9.5 断言与前置条件
  • 明确断言:使用断言库(如JUnit、Mocha、Pytest)验证结果。

    // C#示例
    using NUnit.Framework;[Test]
    public void Add_ShouldReturnCorrectSum() {int result = Calculator.Add(2, 3);Assert.AreEqual(5, result);
    }
    
  • 前置条件检查:在测试方法开始前验证必要条件(如数据库连接、文件存在)。

    import osdef test_read_file():file_path = "test.txt"assert os.path.exists(file_path), f"文件 {file_path} 不存在"content = read_file(file_path)assert len(content) > 0
    
9.6 集成测试与端到端测试
  • 集成测试:验证多个模块或组件协同工作的正确性。
    • 使用Mock对象隔离外部依赖(如数据库、第三方API)。
  • 端到端测试:模拟用户真实操作流程,确保系统整体功能正常。
    • 使用工具(如Selenium、Cypress)自动化UI测试。
9.7 测试数据管理
  • 测试数据隔离:避免测试数据污染生产环境,使用独立的测试数据库或沙箱环境。
  • 数据初始化:在测试前准备好必要的测试数据,测试后清理数据以保证独立性。

测试与调试检查清单

  1. 每个测试方法是否只验证一个功能点?
  2. 测试覆盖率是否达到目标要求?
  3. 测试方法命名是否清晰表达了测试内容?
  4. 是否使用分级日志记录信息?
  5. 断言是否准确验证了预期结果?
  6. 测试数据是否与生产环境隔离?

10. 版本控制

10.1 分支策略
  • 主分支(Master/Main)
    • 用于生产环境的稳定代码,仅接受通过测试的合并请求。
    • 禁止直接在主分支提交代码,所有变更需通过其他分支合并。
  • 开发分支(Develop)
    • 作为日常开发的主分支,集成所有功能分支的代码。
    • 定期合并到主分支,并打上版本标签(如 v1.0.0)。
  • 功能分支(Feature)
    • 基于 Develop 分支创建,用于开发新功能或修复缺陷。
    • 命名格式:feature/xxx(如 feature/user-login)。
    • 开发完成后,通过合并请求(MR/PR)合并回 Develop 分支。
  • 发布分支(Release)
    • 基于 Develop 分支创建,用于预发布准备(如版本号更新、文档整理)。
    • 修复此分支上的紧急Bug后,同步合并到 DevelopMaster 分支。
  • 热修复分支(Hotfix)
    • 基于 Master 分支创建,用于修复生产环境的紧急问题。
    • 修复完成后,合并回 MasterDevelop 分支,并更新版本号。

分支管理示例流程

Master
Develop
Feature分支
Release分支
Hotfix分支
10.2 提交信息规范
  • 格式要求:采用 <类型>(<作用域>): <描述> 结构。
    • 类型feat(新功能)、fix(修复Bug)、docs(文档更新)、style(格式调整)、refactor(重构)等。
    • 作用域:可选,标识代码模块(如 user, order)。
    • 描述:简明扼要说明提交内容,不超过50个字符。
  • 示例
    feat(user): 添加用户注册功能
    fix(order): 修复订单支付金额计算错误
    docs(api): 更新接口文档说明
    
  • 多行描述:若需详细说明,可在单行描述后换行添加。
    refactor(cache): 优化缓存读取逻辑1. 使用LRU算法替换旧策略
    2. 减少缓存过期时的并发问题
    
10.3 代码审查流程
  • 强制审查:所有合并请求必须通过至少一名团队成员审查。
  • 审查内容
    • 代码是否符合编码规范。
    • 逻辑正确性与潜在风险(如内存泄漏、安全漏洞)。
    • 单元测试是否完整且通过。
    • 提交信息是否清晰规范。
  • 审查工具:使用GitHub、GitLab或Bitbucket的内置审查功能,或集成专门工具(如Gerrit)。
  • 审查反馈:审查者需明确指出问题并提供修改建议,开发者修改后重新提交审查。
10.4 标签与版本管理
  • 语义化版本(SemVer):采用 MAJOR.MINOR.PATCH 格式。
    • MAJOR:不兼容的API变更。
    • MINOR:向后兼容的功能新增。
    • PATCH:向后兼容的Bug修复。
  • 标签示例
    v1.0.0  # 初始版本
    v1.1.0  # 新增功能
    v1.1.1  # 修复小Bug
    v2.0.0  # 重大架构调整
    
  • 版本发布流程
    1. Release 分支更新版本号。
    2. 执行全面测试并修复发现的问题。
    3. 合并 Release 分支到 MasterDevelop 分支。
    4. Master 分支打上版本标签。
10.5 冲突解决策略
  • 主动合并:定期将 Develop 分支合并到功能分支,减少冲突概率。
  • 解决冲突
    • 使用 git mergetool 等工具辅助解决冲突。
    • 冲突解决后,提交明确的冲突解决说明。
  • 避免强制推送:除非必要,禁止使用 git push --force,防止覆盖他人提交。
10.6 协作规范
  • 禁止直接推送主分支:所有变更必须通过合并请求进行。
  • 分支清理:及时删除已合并的功能分支,保持仓库整洁。
  • 备份与容灾:定期备份代码仓库,防止数据丢失。

版本控制检查清单

  1. 是否遵循标准的分支管理策略?
  2. 提交信息是否符合 <类型>(<作用域>): <描述> 格式?
  3. 合并请求是否经过代码审查?
  4. 版本号是否遵循语义化版本规范?
  5. 冲突解决后是否提交了清晰的说明?

11. 文档与注释

11.1 函数与类注释模板
  • 标准注释结构:包含功能描述、参数说明、返回值、异常抛出等信息。
    /*** 计算两个整数的和** @param num1 第一个整数* @param num2 第二个整数* @return 两数之和* @throws IllegalArgumentException 当参数小于0时抛出异常*/
    public int add(int num1, int num2) {if (num1 < 0 || num2 < 0) {throw new IllegalArgumentException("参数不能为负数");}return num1 + num2;
    }
    
  • Web前端注释:使用JSDoc格式,支持类型标注。
    /*** 格式化日期字符串* @param {string} dateStr - 原始日期字符串(格式:YYYY-MM-DD)* @param {string} format - 目标日期格式(如:MM/DD/YYYY)* @returns {string} 格式化后的日期字符串*/
    function formatDate(dateStr, format) {// 实现逻辑
    }
    
11.2 API文档生成
  • 自动化工具
    • 后端:使用Swagger(OpenAPI)生成RESTful API文档,或通过工具(如Dokka、Javadoc)生成代码级API文档。
    • 前端:使用TypeDoc生成TypeScript文档,或结合Storybook展示组件API。
  • 文档内容
    • 接口描述、请求参数、响应格式、错误码说明。
    • 示例代码和调用流程。
  • 示例(Swagger):
    paths:/users:get:summary: 获取用户列表parameters:- name: pagein: querydescription: 页码required: trueschema:type: integerresponses:200:description: 成功返回用户列表content:application/json:schema:type: arrayitems:$ref: '#/components/schemas/User'
    
11.3 技术文档维护
  • 项目架构文档:记录系统整体架构、模块划分、依赖关系。
    # 系统架构设计
    ## 1. 分层架构
    - 表示层:处理HTTP请求,使用Spring Boot(后端)/React(前端)。  
    - 应用层:协调业务逻辑,调用领域服务。  
    - 领域层:核心业务逻辑,包含实体和值对象。  
    - 基础设施层:数据库访问、消息队列等。  
    
  • 部署文档:说明环境配置、部署步骤、依赖组件版本。
    # 部署指南
    1. 安装Java 17和MySQL 8.0。  
    2. 执行数据库脚本 `init.sql`。  
    3. 打包项目:`mvn clean package`。  
    4. 启动服务:`java -jar target/app.jar`。  
    
  • 维护文档:记录常见问题解决方案、系统监控指标。
    # 常见问题
    - **问题**:服务启动失败,提示端口被占用。  **解决方案**:使用 `lsof -i:<端口号>` 查找占用进程并关闭。  
    
11.4 注释更新原则
  • 同步更新:代码修改后,对应注释和文档必须同步更新。
  • 避免冗余:注释应补充代码逻辑难以表达的信息,而非重复代码。
    // 不推荐:重复代码逻辑
    let total = sum + value; // 将sum和value相加赋值给total// 推荐:解释业务意图
    let total = sum + value; // 计算订单总价,包含商品金额和运费
    
  • 废弃注释:及时删除不再生效的注释,避免误导。
11.5 团队协作规范
  • 文档评审:重要文档(如架构设计、API文档)需通过团队评审。
  • 统一工具:使用Confluence、GitBook等平台集中管理文档。
  • 版本关联:文档版本与代码版本保持对应,便于追溯。

文档与注释检查清单

  1. 函数和类是否包含完整的注释(功能、参数、返回值、异常)?
  2. API文档是否自动生成并及时更新?
  3. 技术文档是否覆盖架构设计、部署流程和维护指南?
  4. 代码修改后,注释和文档是否同步更新?
  5. 团队是否使用统一的文档管理工具?

12. 兼容性与可维护性

12.1 跨平台/浏览器兼容性
  • 前端浏览器兼容

    • 使用CSS前缀(如 -webkit-, -moz-)处理不同浏览器样式差异。
    • 采用渐进增强或优雅降级策略,确保低版本浏览器基本可用。
    /* 兼容不同浏览器的Flexbox */
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    
    • 利用 postcss-preset-envAutoprefixer 自动添加CSS前缀。
    • 测试工具:使用BrowserStack、Sauce Labs或Chrome DevTools的设备模式模拟不同浏览器环境。
  • 后端跨平台部署

    • 避免依赖特定操作系统API(如Windows特有的文件路径格式)。
    • 采用容器化技术(Docker)统一运行环境,确保在Linux、Windows、macOS上一致部署。
    • 数据库连接:使用标准SQL语句,减少对数据库特定方言(如MySQL的 LIMIT 与Oracle的 ROWNUM)的依赖。
12.2 代码复用与DRY原则
  • 提取公共代码:将重复逻辑封装为工具类、组件或函数。
    // 不推荐:重复的日期格式化代码
    const date1 = new Date().toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' });
    const date2 = new Date().toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' });// 推荐:提取为公共函数
    function formatDate() {return new Date().toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' });
    }
    const date1 = formatDate();
    const date2 = formatDate();
    
  • 组件化设计
    • 前端:将UI拆分为可复用的组件(如Vue、React组件)。
    • 后端:通过模块化(如Java的模块系统、C#的命名空间)划分功能。
12.3 技术债务管理
  • 识别技术债务:通过代码审查、静态分析工具(如SonarQube)标记问题代码。
    • 常见债务类型:重复代码、过度复杂逻辑、未修复的缺陷、过时的依赖库。
  • 制定偿还计划
    • 记录债务清单,标注优先级和影响范围。
    • 定期安排时间(如每个迭代周期)处理技术债务。
  • 示例债务记录
    # 技术债务清单
    | 编号 | 描述                     | 优先级 | 影响范围       | 计划修复时间 |
    |------|--------------------------|--------|----------------|-------------|
    | 1    | 用户模块存在重复验证逻辑 | 高     | 用户注册、登录 | 2025-06-30  |
    | 2    | 第三方库lodash版本过低  | 中     | 全局           | 2025-07-15  |
    
12.4 可扩展性设计
  • 接口与抽象层:通过接口或抽象类定义行为,便于扩展实现。
    // 定义支付接口
    interface PaymentGateway {boolean processPayment(double amount);
    }// 具体实现类
    class PayPalGateway implements PaymentGateway {@Overridepublic boolean processPayment(double amount) {// 实现逻辑}
    }
    
  • 配置驱动设计:将可变更的参数(如API地址、功能开关)提取到配置文件中。
    # application.yml
    payment:gateway: paypalapiUrl: https://api.paypal.com
    
12.5 代码可读性与可理解性
  • 变量与函数命名:使用清晰、完整的名称,避免使用模糊缩写。
  • 逻辑拆分:将长方法拆分为多个小函数,每个函数专注单一任务。
    # 不推荐:过长的函数
    def process_order(order):# 验证订单# 计算总价# 处理支付# 生成发货单pass# 推荐:拆分逻辑
    def validate_order(order):passdef calculate_total(order):passdef process_payment(order):passdef generate_shipment(order):pass
    
  • 添加注释:对复杂逻辑、算法或设计决策添加注释说明。

兼容性与可维护性检查清单

  1. 前端代码是否兼容主流浏览器及低版本?
  2. 后端代码是否依赖特定操作系统或数据库方言?
  3. 是否存在重复代码或可复用的逻辑未提取?
  4. 技术债务是否记录并制定了修复计划?
  5. 代码结构是否便于扩展和修改?

13. 附录

13.1 术语表
术语定义
SRP(单一职责原则)每个类/模块只负责一项职责,降低复杂度和维护成本。
OCP(开闭原则)软件实体应对扩展开放,对修改关闭,通过抽象和多态实现。
DRY(不要重复自己)避免重复代码,通过复用和抽象提高效率。
KISS(保持简单)设计应尽量简洁,避免过度复杂。
CSP(内容安全策略)用于防止跨站脚本攻击(XSS)的HTTP头,限制页面可加载的资源来源。
CI/CD(持续集成/持续交付)开发流程中自动构建、测试和部署代码的实践。
ORM(对象关系映射)将数据库表映射为对象模型的工具,简化数据访问层开发。
AOP(面向切面编程)通过分离横切关注点(如日志、事务)提高代码模块化的编程范式。
13.2 参考资源
  • 通用编程规范
    • 《Clean Code: A Handbook of Agile Software Craftsmanship》 - Robert C. Martin
    • 《Design Patterns: Elements of Reusable Object-Oriented Software》 - Erich Gamma等
  • 语言特定规范
    • Microsoft .NET Coding Conventions
    • Google Java Style Guide
    • Airbnb JavaScript Style Guide
    • Android Code Style Guidelines
  • 安全标准
    • OWASP Top Ten
    • CWE/SANS Top 25 Most Dangerous Software Errors
  • 工具与社区
    • 代码审查工具:GitHub Pull Requests, GitLab Merge Requests
    • 静态分析工具:SonarQube, ESLint, Checkstyle
    • 开发者社区:Stack Overflow, Reddit/r/learnprogramming

相关文章:

跨平台编码规范文档

1. 引言 1.1 目的与范围 本编码规范旨在为软件开发团队提供统一的代码编写标准&#xff0c;以提高代码质量、可维护性和团队协作效率。适用于使用C#、Java、安卓和Web前端&#xff08;HTML/CSS/JavaScript/TypeScript&#xff09;的项目开发&#xff0c;不针对特定语言特性&a…...

Spring创建的线程池

在自动审核的方法上加上Async注解&#xff08;标明要异步调用&#xff09; Async//异步方法调用public void audit(WmNews wmNews) {//这个方法处理时间很长&#xff0c;单体异步思想&#xff0c;线程池}在自媒体引导类中使用EnableAsync注解开启异步调用 SpringBootApplicati…...

【深度学习新浪潮】苹果在显示算法技术上的研发进展调研

苹果的显示算法技术研发呈现三大趋势:AI深度整合(如HDR增强、动态校准)、多模态环境感知(光、温湿度、生物特征)、软硬件协同优化(芯片、传感器、算法深度耦合)。 一、动态刷新率与功耗管理 1. ProMotion技术的算法升级 技术修正: 像素级功耗管理:iPhone 13系列的Pr…...

图像画质算法记录(前言)

一、背景介绍 本篇主要是对图像画质增强相关&#xff0c;进行简单整理和记录。 二、整体流程 整体效果主要受到两部分影响&#xff1a; 1、前端isp处理。 2、后端画质增强。 三、isp常规流程 可以参考&#xff1a;刘斯宁&#xff1a;Understanding ISP Pipeline 四、后端画质…...

uniapp-商城-47-后台 分类数据的生成(通过数据)

在第46章节中&#xff0c;我们为后台数据创建了分类的数据表结构schema&#xff0c;使得可以通过后台添加数据并保存&#xff0c;同时使用云函数进行数据库数据的读取。文章详细介绍了如何通过前端代码实现分类管理功能&#xff0c;包括获取数据、添加、更新和删除分类。主要代…...

阿里云服务器数据库故障排查指南?

阿里云服务器数据库故障排查指南? 以下是针对阿里云服务器&#xff08;如ECS自建数据库或阿里云RDS等托管数据库&#xff09;的故障排查指南&#xff0c;涵盖常见问题的定位与解决方案&#xff1a; 一、数据库连接失败 检查网络连通性 ECS自建数据库 确认安全组规则放行数据库…...

服务器不备案有影响吗

在当今数字化的时代&#xff0c;服务器成为了众多企业和个人开展业务、展示自我的重要工具。然而&#xff0c;有一个问题常常被忽视&#xff0c;那就是服务器不备案到底有没有影响&#xff1f; 答案是肯定的&#xff01;服务器不备案&#xff0c;影响可不小。据相关数据显示&a…...

LVGL9保姆级教程(源码获取)

文章目录 &#x1f31f; LVGL 9 源码获取全流程指南&#x1f4e5; 获取 LVGL 9 源码✅ 官方 GitHub 仓库下载&#x1f4cc; 下载步骤&#xff1a; &#x1f6e0;️ 获取 LVGL Code::Blocks 工程源码下载步骤有两种方式&#xff1a;&#x1f680; 方法一&#xff1a;通过 README…...

【react组件】矩形框选小组件,鼠标左键选中 div,键盘 ESC 清空

在线预览 GitHub demo import React, { useState } from react; import Chooser from rc-chooser;const containerStyle: React.CSSProperties {display: flex,alignItems: center,justifyContent: center,flexWrap: wrap, };const boxStyle: React.CSSProperties {width:…...

数据结构5.0

大家好&#xff0c;今天是队列的知识哦~ 目录 一、概念 1.0单链表 2.0双链表 3.0数组 二、队列的方法 1.0 offer方法 2.0 poll方法 3.0 peek方法 4.0 isEmpty方法 三、队列的题目 1.0 用队列实现栈 2.0 用栈实现队列 3.0 设计循环队列 一、概念 数组 、单链表和双…...

Python字典:数据操作的核心容器

在Python编程生态中&#xff0c;字典&#xff08;dict&#xff09;是最常用且功能强大的内置数据结构之一。它以键值对&#xff08;Key-Value Pair&#xff09;的形式存储数据&#xff0c;为快速查找、灵活映射关系提供了天然支持。无论是数据清洗、算法实现还是Web开发&#x…...

Midjourney-V7:支持参考图片头像或背景生成新保真图

Midjourney-V7重磅升级Omni Reference&#xff1a;全能图像参考神器&#xff01;再也不用担心生成图片货不对版了&#xff01; 就在上周&#xff0c;Midjourney发版它最新的V7版本&#xff1a;Omini Reference&#xff0c;提供了全方位图像参考功能&#xff0c;它可以参考你提…...

【MySQL数据库】--SQLyog创建数据库+python连接

目录 1.连接本地数据库 2.创建数据库和表 3.使用 python读取数据 1.连接本地数据库 进入SQLyog 2.创建数据库和表 创建数据库gyp_test&#xff1a; CREATE DATABASE gyp_test CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; 创建表student_grade: CREATE TABLE …...

深入解析:思维链模型在大语言模型中的应用与实践

在人工智能领域&#xff0c;大语言模型的发展正以前所未有的速度改变着我们的生活和工作方式。从早期的文本生成到如今的复杂推理&#xff0c;模型的能力不断进化。而其中&#xff0c;思维链&#xff08;Chain-of-Thought, CoT&#xff09;技术的出现&#xff0c;更是为大模型的…...

服务器多客户端连接核心要点(1)

刷题 服务器多客户端连接核心要点 多进程服务器 实现原理 fork子进程&#xff1a;每次accept新客户端后&#xff0c;调用fork创建子进程。独立处理&#xff1a;子进程负责与客户端通信&#xff08;如read/write&#xff09;&#xff0c;父进程继续监听新连接。 特点 隔离性…...

SIGIR 2025端到端生成式推荐ETEGRec

文章目录 1. 背景2. 方法2.1 框架图2.2 问题定义2.3 Item Tokenizer2.4 Generative Recommender2.5 ⭐️Sequence-Item Alignment2.6 ⭐️Preference-Semantic Alignment2.7 交替优化 3. 总结 现阶段 GRM 大多是两阶段的模型&#xff0c;第一阶段进行内容理解-行为语义对齐&…...

rust 中的 EBNF 介绍

在 rust 参考手册中&#xff0c;有大量类似&#xff1a; 句法 MacroInvocation :SimplePath ! DelimTokenTreeDelimTokenTree :( TokenTree* )| [ TokenTree* ]| { TokenTree* }TokenTree :Token排除 定界符(delimiters) | DelimTokenTreeMacroInvocationSemi :SimplePath ! (…...

解决 Redis 缓存与数据库一致性问题的技术指南

Redis 缓存与数据库一致性是分布式系统中常见的挑战&#xff0c;尤其在高并发场景下&#xff08;如电商、用户管理、对账系统&#xff09;。Redis 作为高性能缓存&#xff0c;常用于加速数据访问&#xff0c;但其与数据库&#xff08;如 MySQL&#xff09;之间的数据同步可能因…...

LlamaIndex 第六篇 SimpleDirectoryReader

SimpleDirectoryReader 是将本地文件数据加载到 LlamaIndex 的最简单方式。虽然在实际生产场景中&#xff0c;您更可能需要使用 LlamaHub 提供的多种数据读取器&#xff08;Reader&#xff09;&#xff0c;但 SimpleDirectoryReader 无疑是快速入门的理想选择。 支持的文件类型…...

window 显示驱动开发-配置内存段类型

视频内存管理器&#xff08;VidMm&#xff09;和显示硬件仅支持某些类型的内存段。 因此&#xff0c;内核模式显示微型端口驱动程序&#xff08;KMD&#xff09;只能配置这些类型的段。 KMD 可以配置内存空间段和光圈空间段&#xff0c;其中不同&#xff1a; 内存空间段由保存…...

【人工智能学习之动作识别TSM训练与部署】

【人工智能学习之动作识别TSM训练与部署】 基于MMAction2动作识别项目的开发一、MMAction2的安装二、数据集制作三、模型训练1. 配置文件准备2. 关键参数修改3. 启动训练4. 启动成功 ONNX模型部署方案一、环境准备二、执行转换命令 基于MMAction2动作识别项目的开发 一、MMAct…...

PostgreSQL冻结过程

1.冻结过程 冻结过程有两种模式&#xff0c;依特定条件而择其一执行。为方便起见&#xff0c;将这两种模式分别称为惰性模式&#xff08;lazy mode&#xff09;和迫切模式&#xff08;eager mode&#xff09;。 并发清理&#xff08;Concurrent VACUUM&#xff09;通常在内部…...

SSHv2公钥认证示例-Paramiko复用 Transport 连接

在 Paramiko 中复用 Transport 连接时&#xff0c;若要通过 公钥认证&#xff08;而非密码&#xff09;建立连接&#xff0c;需手动加载私钥并与 Transport 关联。以下是详细操作步骤及完整代码示例&#xff1a; 步骤 1&#xff1a;加载私钥文件 使用 RSAKey 或 Ed25519Key 类…...

华为5.7机考-最小代价相遇的路径规划Java题解

题目内容 输入描述 输出描述 示例&#xff1a; 输入&#xff1a; 2 1 2 2 1 输出&#xff1a; 3 思路&#xff1a; Dijkstra 算法实现 dijkstra(int sx, int sy, int[][] dirs) 方法&#xff1a; 参数&#xff1a;起点坐标 (sx, sy) 和允许的移动方向 初始化&#xff1…...

element-ui分页的使用及修改样式

1.安装 npm install element-ui -S 2.在main.js中引入,这里是全部引入&#xff0c;也可以按需引入 import ElementUI from element-ui import element-ui/lib/theme-chalk/index.css Vue.use(ElementUI) 3.使用 layout"prev, pager, next, jumper" &#xff1a;jumpe…...

[Unity]-[UI]-[Image] 关于UI精灵图资源导入设置的详细解释

Unity UI Sprite UI资源导入详解图片导入项目Texture TypeTexture ShapeAdvanced Setting 高级设置 图片设置案例常见细节问题 知识点详解来源 UI资源导入详解 Unity中的UI资源有图片、矢量图、字体、预制体、图集、动画等等资源。 这其中图片是最重要以及最基础的资源组成&a…...

MLX-Audio:高效音频合成的新时代利器

MLX-Audio&#xff1a;高效音频合成的新时代利器 现代社会的快节奏生活中&#xff0c;对语音技术的需求越来越高。无论是个性化语音助手&#xff0c;还是内容创作者所需的高效音频生成工具&#xff0c;语音技术都发挥着不可或缺的作用。今天&#xff0c;我们将介绍一个创新的开…...

操作系统导论——第27章 插叙:线程API

关键问题&#xff1a;如何创建和控制线程&#xff1f; 操作系统应该提供哪些创建和控制线程的接口&#xff1f;这些接口如何设计得易用和实用&#xff1f; 一、线程创建 编写多线程程序的第一步就是创建新线程&#xff0c;因此必须存在某种线程创建接口。在 POSIX 中&#xff1…...

代采系统:定义、优势与未来趋势

一、代采系统的定义 代采系统是一种基于互联网的集中采购平台&#xff0c;它通过整合供应链资源&#xff0c;为中小企业或个人提供采购代理服务。商家可以在没有自己库存的情况下销售产品&#xff0c;当客户下单时&#xff0c;订单信息会自动或手动发送给供应商&#xff0c;由…...

后缀表达式+栈(详解)(c++)

前言 很抱歉&#xff0c;上一期没有介绍栈stack的用法&#xff0c;今天简要介绍一下&#xff0c;再讲讲后缀表达式&#xff0c;用stack栈做一些后缀表达式的练习。 栈 栈stack是c中系统给出的栈&#xff0c;有了它&#xff0c;就不用自己创建栈啦&#xff01; 头文件 栈sta…...

Kaggle图像分类竞赛实战总结详细代码解读

前言 我是跟着李沐的动手学深度学习v2视频学习深度学习的&#xff0c;光看不做假把式&#xff0c;所以在学习完第七章-现代卷积神经网络之后&#xff0c;参加了一次李沐发布的Kaggle竞赛。自己动手&#xff0c;从组织数据集开始&#xff0c;到训练&#xff0c;再到推理&#x…...

开源AI对比--dify、n8n

原文网址&#xff1a;开源AI对比--dify、n8n-CSDN博客 简介 本文介绍开源AI工作流工具的选型。 对比 项difyn8n占优者学习难度简单中等dify核心理念用LLM构建应用。“连接一切”。以工作流自动化连接各系统。平手工作模式 Chatflow&#xff1a;对话。支持用户意图识别、上下…...

【SQL系列】多表关联更新

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

软件设计师教程——第一章 计算机系统知识(下)

前言 在竞争激烈的就业市场中&#xff0c;证书是大学生求职的重要加分项。中级软件设计师证书专业性强、认可度高&#xff0c;是计算机相关专业学生考证的热门选择&#xff0c;既能检验专业知识&#xff0c;又有助于职业发展。本教程将聚焦核心重点&#xff0c;以点带面构建知…...

华为银河麒麟 V10(ARM)系统软件部署全攻略:Redis、RabbitMQ、MySQL 等集群搭建指南

一、Redis 集群部署&#xff08;主从 哨兵模式&#xff09; 1. 环境准备 系统&#xff1a;华为银河麒麟 V10&#xff08;ARM64&#xff09;节点&#xff1a;3 台服务器&#xff08;1 主 2 从 3 哨兵&#xff09; 2. 安装包下载 bash # 华为镜像站 wget https://update.c…...

World of Warcraft [CLASSIC][80][Deluyia] [Fragment of Val‘anyr]

瓦兰奈尔的碎片 [Fragment of Valanyr] 有时候下个班打个游戏&#xff0c;没想到套路也这么多&#xff0c;唉&#xff0c;何况现实生活&#xff0c;这一个片版本末期才1000G&#xff0c;30个&#xff0c;也就30000G&#xff0c;时光徽章等同月卡15000G&#xff0c;折合一下也就…...

C++:求分数序列和

【描述】 有一个分数序列 2/1,3/2,5/3,8/5,13/8,21/13,.... 求这个分数序列的前n项之和。 输入 输入有一行&#xff1a;正整数n。 输出 输出有一行&#xff1a;分数序列的和&#xff08;浮点数&#xff0c;精确到小数点后4位&#xff09;。 【样例输入】 99 【样例输出】 160.4…...

支付宝沙盒模式商家转账经常出现 响应异常: 解包错误

2025年5月9日16:27:08 php8.3 laravel11 octane swoole加速 测试时不时就出现 响应异常: 解包错误 错误信息&#xff1a; Yansongda\Artful\Exception\InvalidResponseException: 响应异常: 解包错误 in /opt/www/vendor/yansongda/artful/src/Direction/CollectionDirect…...

第04章—技术突击篇:如何根据求职意向进行快速提升与复盘

经过上一讲的内容阐述后&#xff0c;咱们定好了一个与自身最匹配的期望薪资&#xff0c;接着又该如何准备呢&#xff1f; 很多人在准备时&#xff0c;通常会选择背面试八股文&#xff0c;这种做法效率的确很高&#xff0c;毕竟能在“八股文”上出现的题&#xff0c;也绝对是面…...

数据统计的意义:钱包余额变动

钱包余额变动统计的核心意义在于通过数据可视化实现资金流动的透明化管理&#xff0c;其价值主要体现在以下五个维度&#xff1a; 一、财务健康诊断&#xff08;&#xff09; 资金流动可视化 通过期初/期末余额对比&#xff0c;可快速识别异常波动&#xff08;如连续3个月余额…...

单调栈模版型题目(3)

单调栈型题目贡献法 基本模版 这是数组a中的 首先我们要明白什么叫做贡献&#xff0c;在一个数组b{1,3,5}中&#xff0c;连续包含1的连续子数组为{1}&#xff0c;{1,3}&#xff0c;{1,3,5}&#xff0c;一共有三个&#xff0c;这三个数一共能组成6个连续子数组&#xff0c;而其…...

PostgreSQL 的 pg_advisory_lock 函数

PostgreSQL 的 pg_advisory_lock 函数 pg_advisory_lock 是 PostgreSQL 提供的一种应用级锁机制&#xff0c;它不锁定具体的数据库对象&#xff08;如表或行&#xff09;&#xff0c;而是通过数字键值来协调应用间的并发控制。 锁的基本概念 PostgreSQL 提供两种咨询锁(advi…...

NLP基础

1. 基本概念 自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;是人工智能和语言学领域的一个分支&#xff0c;它涉及到计算机和人类&#xff08;自然&#xff09;语言之间的相互作用。它的主要目标是让计算机能够理解、解释和生成人类语言…...

[AI Tools] Dify 工具插件上传指南:如何将插件发布到官方市场

Dify 作为开源的 LLM 应用开发平台,不仅支持本地化插件开发,也提供了插件市场机制,让开发者能够将自己构建的插件发布并供他人使用。本文将详细介绍如何将你开发的 Dify Tools 插件上传至官方插件市场,包括 README 编写、插件打包、仓库 PR 等核心步骤。 一、准备 README 文…...

Qt读写XML文档

XML 结构与概念简介 XML&#xff08;可扩展标记语言&#xff09; 是一种用于存储和传输结构化数据的标记语言。其核心特性包括&#xff1a; 1、树状结构&#xff1a;XML 数据以层次化的树形结构组织&#xff0c;包含一个根元素&#xff08;Root Element&#xff09;&#xff…...

htmlUnit和Selenium的区别以及使用BrowserMobProxy捕获网络请求

1. Selenium&#xff1a;浏览器自动化之王 核心定位&#xff1a; 跨平台、跨语言的浏览器操控框架&#xff0c;通过驱动真实浏览器实现像素级用户行为模拟。 技术架构&#xff1a; 核心特性&#xff1a; 支持所有主流浏览器&#xff08;含移动端模拟&#xff09; 精…...

C#黑魔法:鸭子类型(Duck Typing)

C#黑魔法&#xff1a;鸭子类型(Duck Typing) 如果它走起路来像鸭子&#xff0c;叫起来像鸭子&#xff0c;那么它就是鸭子。 鸭子类型&#xff0c;主要应用于动态语言类型&#xff0c;比如JS、Python等&#xff0c;核心理念为&#xff1a;关注对象的行为&#xff08;方法或属性…...

2025 年数维杯数学建模B题完整论文代码模型

《2025 年数维杯数学建模B题完整论文代码模型》 B题完整论文 一、赛事背景与题目总览 2025 年第十届数维杯大学生数学建模挑战赛的 B 题聚焦于“马拉松经济的高质量发展思路探索”。近年来&#xff0c;我国马拉松赛事如同一颗颗璀璨的星星&#xff0c;在城市的天空中闪耀&am…...

C++23 中的 views::chunk:深入探索与应用

文章目录 一、views::chunk 的背景与动机二、views::chunk 的基本用法语法与参数示例代码 三、views::chunk 的高级用法处理不完整块与 views::drop 和 views::take 结合 四、性能分析五、应用场景1. 批量处理数据2. 分页显示3. 并行处理 六、与其他范围适配器的组合1. 与 view…...

库室指静脉人脸门禁机 LK-BM-S10C/JR

1、采用大于等于四核处理器&#xff0c;主频大于1G&#xff1b; 2、内存≥4G DDR3&#xff1b;存储≥8G 3、核心模块采用国产工业级处理芯片和嵌入式Android实时多任务系统&#xff0c;采用模块化设计,模块间通过标准接口相连&#xff1b; 4、大于等于10英寸电容屏&#xf…...