MST

星途 面试题库

面试题:TypeScript 封装原则下的访问修饰符使用优化

假设你正在维护一个大型的 TypeScript 项目,部分类的属性和方法使用了 public 访问修饰符,现在需要遵循更好的封装原则对代码进行重构。请说明重构思路,如何恰当地将部分 public 成员转换为 private 或 protected,并确保外部接口的功能不受影响,同时描述在转换过程中可能遇到的问题及解决方案。
35.7万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

重构思路

  1. 分析类的职责与交互
    • 全面梳理每个类的功能以及与其他类之间的交互方式。明确哪些属性和方法是类内部使用,哪些是供外部调用的。
    • 例如,在一个用户管理类UserManager中,如果有一个属性userList用于存储用户信息,而它仅在类内部的方法如getUserById中使用,那么这个属性就不应该是public的。
  2. 将合适的public成员转为private
    • 对于仅在类内部使用的属性和方法,将其访问修饰符从public改为private。这样可以限制外部对这些成员的直接访问,增强封装性。
    • 比如在一个数据处理类DataProcessor中,有一个方法normalizeData用于内部数据格式的标准化,外部不需要直接调用,就可将其改为private
  3. 对于需要在子类中访问的成员转为protected
    • 如果某些成员不仅在当前类内部使用,还需要在子类中访问,那么将其访问修饰符改为protected
    • 例如,一个图形基类Shape有一个属性color,子类CircleRectangle可能需要访问和修改这个颜色属性,就可以将color设为protected
  4. 提供访问器和修改器(getter和setter)
    • 对于改为privateprotected的属性,如果外部需要获取或修改其值,提供相应的gettersetter方法。这些方法可以是public的,以确保外部接口的功能不受影响。
    • User类有一个private属性age,可以提供public getAge(): number { return this.age; }public setAge(newAge: number): void { this.age = newAge; }方法。

可能遇到的问题及解决方案

  1. 编译错误
    • 问题:当将public成员改为privateprotected后,在原来直接访问这些成员的外部代码处会出现编译错误。
    • 解决方案:通过修改外部代码,使用提供的gettersetter方法来访问和修改属性,或者如果是方法,通过类的其他公开方法间接调用这些已修改访问修饰符的方法。
  2. 依赖问题
    • 问题:其他类可能过度依赖这些原本public的成员,改变访问修饰符后可能破坏依赖关系。
    • 解决方案:分析依赖关系,重构依赖的类,使其依赖于公开的接口(如gettersetter方法或其他公开方法),而不是直接依赖于内部成员。
  3. 测试问题
    • 问题:修改访问修饰符后,一些单元测试可能无法直接访问被测试类的某些成员,导致测试失败。
    • 解决方案:调整测试策略,使用类的公开接口来测试功能,而不是直接访问内部成员。如果确实需要访问内部状态进行测试,可以考虑使用反射机制(在TypeScript中可以借助第三方库实现有限的反射功能),但要谨慎使用,因为这可能破坏封装性。