我有时会编写可以转换为 - 和 - 来自其他类的类,我习惯将其编写为非静态转换方法和静态转换方法,例如:
class A {
B toB() {...}
static A fromB(B b) {...}
}
或
class B {
void save(File f) {...}
static B load(File f) {...}
}
我曾经认为这是一个很好而且简单的方法,但是最近转换方法的静态性让我感到烦恼,例如,如果我想为可以转换为 - 和从中转换的类型定义接口 - B
:
interface ConvertableToAndFromB {
B toB();
// ?
}
那么,除了迁移到Smalltalk之外,有没有一种优雅的方法可以做到这一点而不需要转换为静态?
为了澄清,我意识到我可以在界面中添加非静态方法,例如:
interface ConvertableToAndFromB {
B toB();
void fromB(B b);
}
或者,如果我想允许不可变类型(感谢Stripling):
interface ConvertableToAndFromB<T implements ConvertibleToAndFromB<T>> {
B toB();
T fromB(B b);
}
但这需要我在我甚至可以调用它之前创建一个新的A
,如:
A a = new A();
a.fromB(b);
或(对于不可变):
A a = new A();
a = a.fromB(b);
这是我想要避免的(但没有其他解决方案)。我只希望有一个更好的方式。
答案 0 :(得分:3)
您应该能够使您的界面递归通用。我相信语法是这样的:
interface ConvertibleToAndFromB<T implements ConvertibleToAndFromB<T>>{
B toB();
T fromB(B b);
}
class A implements ConvertibleToAndFromB<A> {
B toB() {...}
A fromB(B b);
}
像这样做更强类型的东西具有明显的优势。但是,它确实意味着您必须在调用fromB
时稍微了解所需的实际类型。这种方法有利有弊。
作为旁注,让A
负责生成A
或B
类型的对象违反了单一责任原则,我通常更愿意有一个单独的Converter类或接口来执行这些操作。
Converter<A, B> converter = converterFactory.get<A, B>(A.class, B.class);
B b = converter.from(a);
答案 1 :(得分:1)
通常,fromB方法将实现为复制构造函数。 E.g。
public class A
{
public A(B b)
{
this.someValue = b.someOtherVariable;
}
}
不幸的是,这无法帮助您创建抽象所述功能的界面。通常,可以使用单独的工厂,并且此工厂实现了一个接口,但这仍然不允许您以非静态方式实现对象中的方法,同时避免不必要的实例化。
答案 2 :(得分:0)
在你的场景中,我会这样做:
interface ConvertableToA {
A toA() {...}
}
interface ConvertableFromA {
Object fromA(A a) {...}
}
class MyConvertableClass implements ConvertableToA, ConvertableFromA {
...
}
答案 3 :(得分:0)
创建实用程序帮助程序类可能更好,因为如果你考虑它,对话与对象/实例无关。
例如,当您将数组转换为列表时,不执行arr.asList(),而是使用Arrays.asList(arr)