这种在类中使用interface类型的实现方式是否合理,有无更优替代方案?
接口实现方案合理性及优化方案
现有方案的合理性分析
语法层面你的代码可以正常运行,但设计上存在明显缺陷:
- 硬耦合问题:
OtherClass直接依赖具体实现类ClassWithInterfaces,后续如果要替换Interface1或Interface2的实现,必须修改OtherClass的源码,违反开闭原则 - 实例一致性风险:如果
someMethod被多次调用,会重复生成ClassWithInterfaces实例,导致interface1和interface2指向的对象不一致,也会产生不必要的性能开销
无DI框架的优化方案
你不需要用第三方DI框架,用纯手动的代码优化就能解决问题,推荐按优先级选择以下方案:
1. 手动构造函数注入(最推荐)
手动依赖注入不需要任何框架支持,是最符合设计规范的实现:
public class OtherClass { private readonly Interface1 _interface1; private readonly Interface2 _interface2; // 依赖从构造函数传入,由上层调用方决定具体实现 public OtherClass(Interface1 interface1, Interface2 interface2) { _interface1 = interface1 ?? throw new ArgumentNullException(nameof(interface1)); _interface2 = interface2 ?? throw new ArgumentNullException(nameof(interface2)); } public void someMethod() { // 直接使用注入的接口实例,不需要内部创建 _interface1.method1(); _interface2.method2(); } } // 上层调用处初始化代码 var impl = new ClassWithInterfaces(); var manager = new OtherClass(impl, impl);
方案优势:
- 完全解耦
OtherClass和具体实现类,后续替换实现仅需修改上层初始化逻辑即可 - 保证两个接口指向的实例完全一致
- 方便单元测试,可直接mock接口实现传入测试
2. 单例模式复用实例
如果ClassWithInterfaces是无状态的,全局仅需一个实例,可以用单例模式统一管理:
class ClassWithInterfaces : Interface1,Interface2 { // 饿汉式单例实现 private static readonly ClassWithInterfaces _instance = new ClassWithInterfaces(); public static ClassWithInterfaces Instance => _instance; // 私有构造函数禁止外部随意实例化 private ClassWithInterfaces() {} void method1() {} void method2() {} } // OtherClass实现 public class OtherClass { private readonly Interface1 _interface1 = ClassWithInterfaces.Instance; private readonly Interface2 _interface2 = ClassWithInterfaces.Instance; public void someMethod() { _interface1.method1(); _interface2.method2(); } }
3. 内部懒加载保证实例一致
如果确实需要在OtherClass内部创建实例,至少要做懒加载避免重复实例化:
public class OtherClass { private Interface1 _interface1; private Interface2 _interface2; private readonly object _lockObj = new object(); public void someMethod() { // 双重校验锁保证线程安全,仅初始化一次 if (_interface1 == null || _interface2 == null) { lock (_lockObj) { if (_interface1 == null || _interface2 == null) { var impl = new ClassWithInterfaces(); _interface1 = impl; _interface2 = impl; } } } // 后续业务逻辑 } }
内容的提问来源于stack exchange,提问作者Jake47
相关产品推荐
相关产品推荐

