奇怪的界面设计Java
Strange interface design Java
在工作中,我在一个 java 项目中遇到了以下设计:
考虑接口 Foo
、Bar
和 Baz
如下:
interface Bar { public int a(); }
interface Baz { public int b(); }
interface Foo extends Bar, Baz { public int c(); }
现在,考虑 class FooImpl
:
public class FooImpl implements Foo {
private Bar bar;
private Baz baz;
public int a() {
return bar.a();
}
public int b() {
return baz.b();
}
public int c() {
return 0;
}
}
这种 class 层次结构的用例是什么?在我看来,这引入了很多样板并且在抽象方面没有增加太多,除了将可能是大文件的文件分解成较小的文件。
它允许这样的事情:
Foo foo = new FooImpl();
useBar(foo);
public void useBar(Bar bar) {
bar.a();
}
这是否有用取决于真实上下文。您带有 类 的示例代码和名称无意义的方法不支持理性判断。
另一件需要注意的事情是您的 FooImpl
实际上是作为 Bar
和 Baz
实例的某种包装器实现的。这不是(严格来说)界面设计问题。
这样做实际上只是使用其属性(bar 和 baz)"a" 方法和 "b" 方法
重定向 fooimpl
我认为这是 多重继承 的解决方法(Java 中不允许)。您没有显示 Bar
和 Baz
的实现,但我们假设它们存在:
public class BarImpl implements Bar {
@Override
public int a() {
return 1;
}
}
public class BazImpl implements Baz {
@Override
public int b() {
return 2;
}
}
您都没有告诉我们 Bar
和 Baz
属性是如何实例化并设置为 FooImpl
,因为如果按照您的问题所述执行,您将得到 NullPointerException
在 FooImpl.a()
和 FooImpl.b()
中。同样,让我们想象一下这是如何实现的:
public class FooImpl implements Foo {
private Bar bar; // better if final
private Baz baz; // better if final
// Constructor to properly initialize bar and baz
public FooImpl(Bar bar, Baz baz) {
this.bar = bar;
this.baz = baz;
}
@Override
public int a() {
return bar.a();
}
@Override
public int b() {
return baz.b();
}
@Override
public int c() {
return 0;
}
}
连接一切:
Bar bar = new BarImpl();
Baz baz = new BazImpl();
Foo foo = new FooImpl(bar, baz);
int one = foo.bar(); // 1
int two = foo.baz(); // 2
在某种程度上,FooImpl
是 BarImpl
和 BazImpl
的 "inheriting",尽管这是通过委托实现的。
在工作中,我在一个 java 项目中遇到了以下设计:
考虑接口 Foo
、Bar
和 Baz
如下:
interface Bar { public int a(); }
interface Baz { public int b(); }
interface Foo extends Bar, Baz { public int c(); }
现在,考虑 class FooImpl
:
public class FooImpl implements Foo {
private Bar bar;
private Baz baz;
public int a() {
return bar.a();
}
public int b() {
return baz.b();
}
public int c() {
return 0;
}
}
这种 class 层次结构的用例是什么?在我看来,这引入了很多样板并且在抽象方面没有增加太多,除了将可能是大文件的文件分解成较小的文件。
它允许这样的事情:
Foo foo = new FooImpl();
useBar(foo);
public void useBar(Bar bar) {
bar.a();
}
这是否有用取决于真实上下文。您带有 类 的示例代码和名称无意义的方法不支持理性判断。
另一件需要注意的事情是您的 FooImpl
实际上是作为 Bar
和 Baz
实例的某种包装器实现的。这不是(严格来说)界面设计问题。
这样做实际上只是使用其属性(bar 和 baz)"a" 方法和 "b" 方法
重定向 fooimpl我认为这是 多重继承 的解决方法(Java 中不允许)。您没有显示 Bar
和 Baz
的实现,但我们假设它们存在:
public class BarImpl implements Bar {
@Override
public int a() {
return 1;
}
}
public class BazImpl implements Baz {
@Override
public int b() {
return 2;
}
}
您都没有告诉我们 Bar
和 Baz
属性是如何实例化并设置为 FooImpl
,因为如果按照您的问题所述执行,您将得到 NullPointerException
在 FooImpl.a()
和 FooImpl.b()
中。同样,让我们想象一下这是如何实现的:
public class FooImpl implements Foo {
private Bar bar; // better if final
private Baz baz; // better if final
// Constructor to properly initialize bar and baz
public FooImpl(Bar bar, Baz baz) {
this.bar = bar;
this.baz = baz;
}
@Override
public int a() {
return bar.a();
}
@Override
public int b() {
return baz.b();
}
@Override
public int c() {
return 0;
}
}
连接一切:
Bar bar = new BarImpl();
Baz baz = new BazImpl();
Foo foo = new FooImpl(bar, baz);
int one = foo.bar(); // 1
int two = foo.baz(); // 2
在某种程度上,FooImpl
是 BarImpl
和 BazImpl
的 "inheriting",尽管这是通过委托实现的。