【问题标题】:Best practices in achieving a great cohesion from multiple interfaces从多个界面实现良好凝聚力的最佳实践
【发布时间】:2014-10-11 23:33:51
【问题描述】:

首先,很抱歉我的措辞不完善,如果有不清楚的地方请告诉我。

在构建 Java 应用程序的类结构时,我想知道在我的案例中是否存在我尚未找到的已知最佳实践。

例如,有A、B、C等多个类指定设备类型,每个设备都有分词器、解析器和编译器。

首先,我有四个这样的接口。

interface Device {
    public void x();
    public int y();
    public String z();
    ...
}

interface Tokenizer {...}

interface Parser {...}

interface Compiler {...}

而且,实际的具体类是,

public class ADevice implements Device {...}
public class BDevice implements Device {...}
public class CDevice implements Device {...}

class ATokenizer implements Tokeninzer {...}
class BTokenizer implements Tokeninzer {...}
class CTokenizer implements Tokeninzer {...}

class AParser implements Parser {...}
...

class ACompiler implements Compiler {...}
...

另外且重要的是,“设备”类及其接口是公开的,因此将包含在存根库中。其他任何内容都将仅包含在实际库中,并且对通过引用 API 生成脚本的用户不可见。


这是我的问题,(长介绍:[)

如何实现每种类型及其对应接口之间的内聚。

更详细地说,有没有办法在编译时确定它们是否在每种类型的设备接口及其对应的标记器、解析器或编译器接口之间正确配对?

例如,有一个使用“Device”对象和“Tokenizer”、“Parser”和“Compiler”对象的管理器类。如您所见,“ADevice”对象只能与“ATokenizer”、“AParser”或“ACompiler”成对出现。但是,如果我们从接口定义设备对象的类型,那么我们无法判断这些对象是否对应于正确的“Tokenizer”、“Parser”或“Compiler”对象,除了“instanceOf”操作员在运行时。 比如“ADevice”可以匹配“BTokenizer”、“CParser”等,不会产生编译错误。

我希望我想听到一个好的答案或重定向到参考。

【问题讨论】:

  • 不同的设备实现有何不同?能举个例子吗?
  • 欢迎光临,别担心,我们喜欢长篇介绍!你能明确说明 A、B 和 C 代表什么吗?我相信泛型会优雅地解决您的问题。

标签: java design-patterns architecture interface structure


【解决方案1】:

一种解决方案是将您的界面参数化:

interface Tokenizer<D extends Device> { ... }
interface Parser<D extends Device> { ... }
interface Compiler<D extends Device> { ... } 

那么你的实现将是:

class ATokenizer implements Tokeniser<ADevice> { ... }
class BTokenizer implements Tokenizer<BDevice> { ... }
class CTokenizer implements Tokenizer<CDevice> { ... }

class AParser implements Parser<ADevice> { ... }
.
.
.
class ACompiler implements Compiler<ADevice> { ... }

然后您可以在 Manager 类中使用一个方法将它们限制为相同的类型:

public <D extends Device> void doStuff(Tokeizer<D> tokenizer, Parser<D> parser, Compiler<D> compiler) { ... }

然后编译器将只允许按照您的描述使用它:

doStuff(new ATokeizer(), new AParser(), new ACompiler()); // works

doStuff(new ATokeizer(), new AParser(), new BCompiler()); // compiler error

【讨论】:

  • 谢谢。这对我有很大帮助:)
【解决方案2】:

您是否考虑过泛型接口?

界面如下:

public interface Parser<E extends Device> {
    void parse(E device);
    void parse(String someString);

}

你可以这样创建类:

public class AParser implements Parser<ADevice> {

    @Override
    public void parse(ADevice device) {
        //parse...
    }

    @Override
    void parse(String someString) {
        //parse...
    }

}

【讨论】:

  • 感谢您的回答。 :]
猜你喜欢
  • 1970-01-01
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 2015-09-28
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 2010-10-07
相关资源
最近更新 更多