我怎样才能更好地组织我的 java 类来使用委托,而不是单调乏味?

问题描述 投票:0回答:1

我有一个 Java 项目,其中一个非常大的类被拆分成较小的类,这完全是出于可读性的原因。使用 Guice 依赖注入。

public interface FooDataService { Foo getFoo(){} }
public class FooDataServiceImpl implements FooDataService { @Override Foo getFoo(){} }
// Also BarDataService, BazDataService, and more


public interface DataService extends FooDataService, BarDataService {}
public class DataServiceImpl implements DataService {
    private final FooDataService fooDataService;
    private final BarDataService barDataService;
    // ...

    @Inject
    public DataServiceImpl(FooDataService fooDataService, BarDataService barDataService) {
        this.fooDataService = fooDataService;
        this.barDataService = barDataService;
        // ...
    }
    
    @Override Foo getFoo(){ return fooDataService.getFoo(); }
    @Override Bar getBar(){ return barDataService.getBar(); }
    // A very large number of methods follow.
}


// Usage
public class ApiService {
    // The idea was to only inject the one dataService variable instead of injecting FooService, BarService, etc.
    // There's not really place where FooDataService is used but not BarDataService, except unit tests
    @Inject
    private final static DataService dataService;

    public void doThing() {
      dataService.getFoo();
      dataService.getBar();
    }
}

这很好,因为它使所有 XDataService 类都相对较小。 DataServiceImpl 本身过去有 2000 多行。 但这有点令人厌烦。

  1. 随着我们添加更多的方法,DataServiceImpl 现在有 600 行长,很难找到任何方法在文件中的位置。 DataServiceImpl 现在也很频繁地遇到合并冲突,因为多个开发人员正在向它添加功能。
  2. 如果我们需要向 FooDataService 添加新方法或更改函数签名,我们必须在 4 个地方进行,这很烦人。
  3. 偶尔,FooDataService 需要调用 BarDataService 中的一个方法,这打破了类之间很好的职责分离。

是否有更好的方法来实现它,以便我们可以拥有小型的、可读性强的课程?

java oop design-patterns guice
1个回答
0
投票

Lombok 的@Delegate 在这里会有帮助——但它目前只是一个实验性功能。 此注释允许您消除样板代码(对委托服务的直接调用):

public interface DataService extends FooDataService, BarDataService {}

public class DataServiceImpl implements DataService {
    @Delegate(FooDataService.clas)
    private final FooDataService fooDataService;
    @Delegate(BarDataService.clas)
    private final BarDataService barDataService;
    
    // no more doFoo(x) { fooService.doFoo(x) } 
    // only the code that does delegate here.
}

如果您觉得这很有趣,请在他们的官方文档中阅读更多相关信息:https://projectlombok.org/features/experimental/Delegate


第二种方法是将直接委托移动到界面本身:

public interface DataService extends FooDataService, BarDataService {
    FooDataService fooService();
    BarDataService barService(); // new "accessor" methods in the interface

    @Override
    default Foo getFoo(){ return fooService().getFoo(); }

    @Override
    default Foo getBar(){ return barService().getBar(); }
    
    // other delegates here
}

有了这个解决方案,如果你改变了什么,你仍然需要在所有地方改变它。但至少

DataServiceImpl
可以专注于它做的事情,除了代表团

© www.soinside.com 2019 - 2024. All rights reserved.