如何优化多层对象间主对象引用共享?替代构造函数传递方案
对象间共享引用的优化方案
在多层对象调用场景中,深层对象需要访问上层对象引用时,通过构造函数层层传递会导致代码冗余、维护性下降。以下是具体场景及更优解决方案:
原问题场景(无法编译代码)
原代码中TestProgram5.DoFinal()需要TestProgram1的引用但未传入,直接导致编译失败:
public class Program { static void Main(string[] args) { var test1 = new TestProgram1(); test1.DoSomething(); } } public class TestProgram1 { public string Name { get; set; } = "TESTING NAME"; public void DoSomething() { var test2 = new TestProgram2(); test2.DoSomething(); } } public class TestProgram2 { public void DoSomething() { var test3 = new TestProgram3(); test3.DoSomething(); } } public class TestProgram3 { public void DoSomething() { var test4 = new TestProgram4(); test4.DoSomething(); } } public class TestProgram4 { public void DoSomething() { var test5 = new TestProgram5(); test5.DoFinal(); // 编译错误:缺少TestProgram1参数 } } public class TestProgram5 { public void DoFinal(TestProgram1 testProgram1) { Console.WriteLine(testProgram1.Name); } }
当前构造函数传递方案
通过构造函数将TestProgram1引用层层传递至TestProgram5,虽能解决问题,但每层都需持有该引用,代码冗余度高:
public class Program { static void Main(string[] args) { var test1 = new TestProgram1(); test1.DoSomething(); } } public class TestProgram1 { public string Name { get; set; } = "TESTING NAME"; public void DoSomething() { var test2 = new TestProgram2(this); test2.DoSomething(); } } public class TestProgram2 { private TestProgram1 TestProgram1 { get; } public TestProgram2(TestProgram1 testProgram1) { TestProgram1 = testProgram1; } public void DoSomething() { var test3 = new TestProgram3(TestProgram1); test3.DoSomething(); } } public class TestProgram3 { private TestProgram1 TestProgram1 { get; } public TestProgram3(TestProgram1 testProgram1) { TestProgram1 = testProgram1; } public void DoSomething() { var test4 = new TestProgram4(TestProgram1); test4.DoSomething(); } } public class TestProgram4 { private TestProgram1 TestProgram1 { get; } public TestProgram4(TestProgram1 testProgram1) { TestProgram1 = testProgram1; } public void DoSomething() { var test5 = new TestProgram5(); test5.DoFinal(TestProgram1); } } public class TestProgram5 { public void DoFinal(TestProgram1 testProgram1) { Console.WriteLine(testProgram1.Name); } }
更优解决方案
1. 使用依赖注入容器
借助DI容器(如.NET Core内置DI)管理对象创建与依赖注入,无需手动层层传递引用,容器会自动解析并注入所需依赖:
public class Program { static void Main(string[] args) { // 构建DI容器 var services = new ServiceCollection(); services.AddSingleton<TestProgram1>(); services.AddTransient<TestProgram2>(); services.AddTransient<TestProgram3>(); services.AddTransient<TestProgram4>(); services.AddTransient<TestProgram5>(); var provider = services.BuildServiceProvider(); var test1 = provider.GetRequiredService<TestProgram1>(); test1.DoSomething(); } } public class TestProgram1 { public string Name { get; set; } = "TESTING NAME"; private readonly TestProgram2 _testProgram2; // 构造函数注入TestProgram2 public TestProgram1(TestProgram2 testProgram2) { _testProgram2 = testProgram2; } public void DoSomething() { _testProgram2.DoSomething(); } } public class TestProgram2 { private readonly TestProgram3 _testProgram3; public TestProgram2(TestProgram3 testProgram3) { _testProgram3 = testProgram3; } public void DoSomething() { _testProgram3.DoSomething(); } } public class TestProgram3 { private readonly TestProgram4 _testProgram4; public TestProgram3(TestProgram4 testProgram4) { _testProgram4 = testProgram4; } public void DoSomething() { _testProgram4.DoSomething(); } } public class TestProgram4 { private readonly TestProgram5 _testProgram5; private readonly TestProgram1 _testProgram1; // 直接注入TestProgram1和TestProgram5 public TestProgram4(TestProgram5 testProgram5, TestProgram1 testProgram1) { _testProgram5 = testProgram5; _testProgram1 = testProgram1; } public void DoSomething() { _testProgram5.DoFinal(_testProgram1); } } public class TestProgram5 { public void DoFinal(TestProgram1 testProgram1) { Console.WriteLine(testProgram1.Name); } }
2. 封装上下文对象
将需要共享的数据或引用封装到统一的上下文类中,仅传递上下文对象,减少依赖传递的数量:
// 定义上下文类,包含共享数据 public class OperationContext { public TestProgram1 TestProgram1 { get; set; } } public class Program { static void Main(string[] args) { var context = new OperationContext { TestProgram1 = new TestProgram1() }; context.TestProgram1.DoSomething(context); } } public class TestProgram1 { public string Name { get; set; } = "TESTING NAME"; public void DoSomething(OperationContext context) { var test2 = new TestProgram2(); test2.DoSomething(context); } } public class TestProgram2 { public void DoSomething(OperationContext context) { var test3 = new TestProgram3(); test3.DoSomething(context); } } public class TestProgram3 { public void DoSomething(OperationContext context) { var test4 = new TestProgram4(); test4.DoSomething(context); } } public class TestProgram4 { public void DoSomething(OperationContext context) { var test5 = new TestProgram5(); test5.DoFinal(context.TestProgram1); } } public class TestProgram5 { public void DoFinal(TestProgram1 testProgram1) { Console.WriteLine(testProgram1.Name); } }
3. 传递必要数据而非整个对象
如果TestProgram5仅需要TestProgram1的某属性(如Name),直接传递该属性值即可,避免传递整个对象引用:
public class Program { static void Main(string[] args) { var test1 = new TestProgram1(); test1.DoSomething(); } } public class TestProgram1 { public string Name { get; set; } = "TESTING NAME"; public void DoSomething() { var test2 = new TestProgram2(); test2.DoSomething(Name); } } public class TestProgram2 { public void DoSomething(string name) { var test3 = new TestProgram3(); test3.DoSomething(name); } } public class TestProgram3 { public void DoSomething(string name) { var test4 = new TestProgram4(); test4.DoSomething(name); } } public class TestProgram4 { public void DoSomething(string name) { var test5 = new TestProgram5(); test5.DoFinal(name); } } public class TestProgram5 { public void DoFinal(string name) { Console.WriteLine(name); } }
4. 使用事件发布订阅模式
让TestProgram1发布事件,TestProgram5订阅该事件,无需直接传递引用,实现对象间解耦:
public class Program { static void Main(string[] args) { var test1 = new TestProgram1(); var test5 = new TestProgram5(); // 订阅事件 test1.NameRequested += test5.OnNameRequested; test1.DoSomething(); } } public class TestProgram1 { public string Name { get; set; } = "TESTING NAME"; // 定义事件 public event Action<string> NameRequested; public void DoSomething() { var test2 = new TestProgram2(); test2.DoSomething(this); } // 触发事件的方法 public void RaiseNameRequested() { NameRequested?.Invoke(Name); } } public class TestProgram2 { public void DoSomething(TestProgram1 test1) { var test3 = new TestProgram3(); test3.DoSomething(test1); } } public class TestProgram3 { public void DoSomething(TestProgram1 test1) { var test4 = new TestProgram4(); test4.DoSomething(test1); } } public class TestProgram4 { public void DoSomething(TestProgram1 test1) { // 触发事件 test1.RaiseNameRequested(); } } public class TestProgram5 { public void OnNameRequested(string name) { Console.WriteLine(name); } }
内容的提问来源于stack exchange,提问作者Паша Мостов
相关产品推荐
相关产品推荐

