面试题答案
一键面试重构思路
- 分析类的职责与交互:
- 全面梳理每个类的功能以及与其他类之间的交互方式。明确哪些属性和方法是类内部使用,哪些是供外部调用的。
- 例如,在一个用户管理类
UserManager
中,如果有一个属性userList
用于存储用户信息,而它仅在类内部的方法如getUserById
中使用,那么这个属性就不应该是public
的。
- 将合适的
public
成员转为private
:- 对于仅在类内部使用的属性和方法,将其访问修饰符从
public
改为private
。这样可以限制外部对这些成员的直接访问,增强封装性。 - 比如在一个数据处理类
DataProcessor
中,有一个方法normalizeData
用于内部数据格式的标准化,外部不需要直接调用,就可将其改为private
。
- 对于仅在类内部使用的属性和方法,将其访问修饰符从
- 对于需要在子类中访问的成员转为
protected
:- 如果某些成员不仅在当前类内部使用,还需要在子类中访问,那么将其访问修饰符改为
protected
。 - 例如,一个图形基类
Shape
有一个属性color
,子类Circle
和Rectangle
可能需要访问和修改这个颜色属性,就可以将color
设为protected
。
- 如果某些成员不仅在当前类内部使用,还需要在子类中访问,那么将其访问修饰符改为
- 提供访问器和修改器(getter和setter):
- 对于改为
private
或protected
的属性,如果外部需要获取或修改其值,提供相应的getter
和setter
方法。这些方法可以是public
的,以确保外部接口的功能不受影响。 - 如
User
类有一个private
属性age
,可以提供public getAge(): number { return this.age; }
和public setAge(newAge: number): void { this.age = newAge; }
方法。
- 对于改为
可能遇到的问题及解决方案
- 编译错误:
- 问题:当将
public
成员改为private
或protected
后,在原来直接访问这些成员的外部代码处会出现编译错误。 - 解决方案:通过修改外部代码,使用提供的
getter
和setter
方法来访问和修改属性,或者如果是方法,通过类的其他公开方法间接调用这些已修改访问修饰符的方法。
- 问题:当将
- 依赖问题:
- 问题:其他类可能过度依赖这些原本
public
的成员,改变访问修饰符后可能破坏依赖关系。 - 解决方案:分析依赖关系,重构依赖的类,使其依赖于公开的接口(如
getter
和setter
方法或其他公开方法),而不是直接依赖于内部成员。
- 问题:其他类可能过度依赖这些原本
- 测试问题:
- 问题:修改访问修饰符后,一些单元测试可能无法直接访问被测试类的某些成员,导致测试失败。
- 解决方案:调整测试策略,使用类的公开接口来测试功能,而不是直接访问内部成员。如果确实需要访问内部状态进行测试,可以考虑使用反射机制(在TypeScript中可以借助第三方库实现有限的反射功能),但要谨慎使用,因为这可能破坏封装性。