You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中如何避免代码重复实现DRY原则?附具体场景

嘿,你已经用基类继承来复用代码了,这本身就踩中了DRY原则的核心!不过我可以给你几个进阶方案,让你的代码复用更灵活,也能应对更多场景:

一、优化现有基类继承的写法

你的BaseClass思路完全没问题,我们可以把它和枚举放到单独的通用文件里,让所有需要的组件统一导入,避免重复定义:

// base.utils.ts
export enum RepeatEnum { 
  one, 
  two 
}

export class BaseClass { 
  public repeatProperty: RepeatEnum = RepeatEnum.one; 

  repeatMethod(): boolean { 
    return this.repeatProperty === RepeatEnum.two; 
  } 
}

之后在任意组件里,只需要导入并继承就能复用所有逻辑:

// x-component.ts
import { BaseClass, RepeatEnum } from './base.utils';
import { OnInit } from '@angular/core';

export class XComponent extends BaseClass implements OnInit { 
  constructor() { 
    super(); 
    this.repeatProperty = RepeatEnum.two; // 按需修改属性值
  }

  ngOnInit(): void {
    // 组件自身的业务逻辑
  }
}

这样所有组件都不用重复写repeatProperty和repeatMethod,完美实现复用。

二、用混入(Mixins)解决多重继承限制

如果你的组件已经需要继承其他类(比如Angular的某些内置基类,或者自定义的其他基类),TypeScript不支持多重继承,这时候混入就是绝佳替代方案。我们把复用逻辑封装成混入函数:

// repeat.mixin.ts
import { RepeatEnum } from './base.utils';

// 定义混入的类型约束
export type RepeatMixinType = {
  repeatProperty: RepeatEnum;
  repeatMethod: () => boolean;
};

// 混入函数,接收一个基类并返回带有复用逻辑的新类
export function RepeatMixin<T extends new (...args: any[]) => {}>(Base: T) {
  return class extends Base implements RepeatMixinType {
    repeatProperty: RepeatEnum = RepeatEnum.one;

    repeatMethod(): boolean {
      return this.repeatProperty === RepeatEnum.two;
    }
  };
}

然后在组件里这样使用:

// x-component.ts
import { OnInit } from '@angular/core';
import { RepeatMixin } from './repeat.mixin';

// 假设组件已经需要继承这个自定义基类
class MyExistingBaseComponent {}

// 通过混入把复用逻辑和现有基类结合
export class XComponent extends RepeatMixin(MyExistingBaseComponent) implements OnInit { 
  constructor() { 
    super(); 
    this.repeatProperty = RepeatEnum.two;
  }

  ngOnInit(): void {
    // ...
  }
}

这种方式能让你把多个独立的复用逻辑组合到一个组件里,比单一继承灵活得多。

三、用服务(Service)复用无状态通用逻辑

如果你的repeatMethod是无状态的(比如不需要依赖组件的实例属性,只是处理通用判断逻辑),可以把它放到Angular服务里,这样不仅组件能用,其他服务、管道甚至指令都能复用:

// repeat.service.ts
import { Injectable } from '@angular/core';
import { RepeatEnum } from './base.utils';

@Injectable({ providedIn: 'root' })
export class RepeatService {
  checkRepeatStatus(value: RepeatEnum): boolean {
    return value === RepeatEnum.two;
  }
}

然后在组件里注入使用:

// x-component.ts
import { OnInit } from '@angular/core';
import { RepeatService, RepeatEnum } from './repeat.service';

export class XComponent implements OnInit { 
  public repeatProperty: RepeatEnum = RepeatEnum.one;

  constructor(private repeatService: RepeatService) {}

  ngOnInit(): void {
    const isRepeatTwo = this.repeatService.checkRepeatStatus(this.repeatProperty);
    // 基于结果做后续处理
  }
}

这种方式的优势是解耦性更强,把通用逻辑和组件状态彻底分开。


内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:02:56