我正在开发一个应用程序,其中我有两个非常相似的对象类,其字段需要规范化。许多需要规范化的字段由这两个类共享,但有一些仅与一个或另一个类相关。
我正在考虑为所有需要规范化的字段创建一个带有getter和setter的接口,这样我就可以将两个对象传递给同一个类并访问字段/通过接口方法设置规范化值。这会被视为糟糕的惯例吗?
下面是简化示例 - 我正在规范化的对象只有在标准化完成后才能读取。提前谢谢!
class A implements C{
T x;
T y;
T z;
...
}
class B implements C{
T x;
T y;
T k; // no 'z', above has no k
....
}
interface C {
public T getX();
public void setX(T x);
public T getY();
public void setY(T y);
public T getZ();
public void setZ(T z);
public T getK();
public void setK(T k);
}
答案 0 :(得分:1)
如果代码已正确记录,说明A
不支持
public T getK();
public void setK(T k);
且B
不支持
public T getZ();
public void setZ(T z);
然后我认为你可以继续这个设计。
并且,还为不支持UnsupportedOperationException
的某些方法的类构造具有指定详细消息的C
。例如,
class A implements C{
T x;
T y;
T z;
...
public T getK(){
throw new UnsupportedOperationException("YOUR MESSAGE");
}
}
答案 1 :(得分:1)
是不是实现了一个接口并为空实现提供了一个糟糕的设计问题?虽然你记录它,它违背了接口的概念并且是不一致的,因为你可能在一个类中有一个方法的空实现,而另一个类中的另一个实现,并且代码将在长期运行中变得不一致,使其不安全。考虑一下
interface iSample {
void doThing1();
void doThing2();
void doThing3();
}
class sClass1 implements iSample {
void doThing1() { //doThing1 code }
void doThing2() { //doThing2 code }
void doThing3() { } // empty implementation
}
class sClass2 implements iSample {
void doThing1() { //doThing1 code }
void doThing2() { } // empty implementation
void doThing3() { //doThing2 code }
}
class Test {
public static void main (String[] args) {
testing(new sClass1());
testing(new sClass2());
}
public void testing(iSample s) {
// you would have no idea here which object has omitted which method.
s.doThing1();
s.doThing2();
s.doThing3();
}
如上所述,你不知道哪个对象省略了哪种方法和不一致。
答案 2 :(得分:0)
那么,根据你的描述,你的两个类中都会有空方法,因为你不需要它们。 class A
将getK
和setK
未实现,class B
将对getZ
和setZ
执行相同操作。
在这种情况下,最好使用具有x
和y
的父类,并将z
和k
的实现保留为{{1分别和class A
。
答案 3 :(得分:0)
高度相似的课程?
这听起来是设计继承的好时机。请注意,设计继承应该是一个非常慎重的决定...因为有一种正确的方法可以使您的API成为一种使用的乐趣,并且错误的方式会使您的API变得麻烦使用。
您也可以按照建议使用基于接口的类型系统。这样做的优点是适用于可能无其他相关的类。
或者你可以做到这两点。
我建议您在类中捕获关系的本质,并将其描述为基于接口的类型系统的合同。
然后,我建议您在抽象骨架实现类中生成合同的骨干实现。您的具体类可以从您的骨架实现继承,如果做得好,将继承描述合同本质的大部分行为和状态。
请注意,您应该使用您的接口作为所有对象的类型名称,就像我们使用Java Collections API一样。不鼓励将参数类型声明为void myFunc(HashMap m)
;最佳做法是宣布void myFunc(Map m)
。在后一种情况下,Map表示Map契约的所有不同实现者的基于接口的类型系统。