假设以下(为了简洁起见,略为伪代码):
class Basic
{
String foo;
}
class SomeExtension extends Basic
{
String bar;
}
class OtherExtension extends Basic
{
String baz;
}
class BasicService
{
Basic getBasic()
{
}
}
class SomeExtensionService extends BasicService
{
SomeExtension getSomeExtension()
{
}
}
class OtherExtensionService extends BasicService
{
OtherExtension getOtherExtension()
{
}
}
使用最可能的代码重用来实现get-()服务方法的最惯用,最优雅的方法是什么?
显然你可以这样做:
class BasicService
{
Basic getBasic()
{
Basic basic = new Basic();
basic.setFoo("some kind of foo");
return basic;
}
}
class SomeExtensionService
{
SomeExtension getSomeExtension()
{
SomeExtension someExtension = new SomeExtension;
Basic basic = getBasic();
someExtension.setFoo(basic.getFoo());
someExtension.setBar("some kind of bar");
return someExtension;
}
}
但是如果Basic有很多属性,那么这将是丑陋的,而且你只需要一个对象,因为SomeExtension已经继承了Basic。但是,BasicService显然不能返回SomeExtension对象。
你也可以让get方法不自己创建对象,但是在最外层创建它并将它传递给方法以填充属性,但我发现这太过于必要。
(如果问题容易混淆,请告诉我。)
编辑:好的,就是这样。我会尝试更好地解释它。假设您有两个模型类A和B.您还有两个类用于返回A类和B类的对象(例如,从数据库中分散信息,因此任何ORM都不适用)。现在,假设A和B包含大量重叠信息,因此重构为超类C并让A和B从中扩展是有意义的。但是,服务类仍然特定于A和B,并且需要复制用于读取重叠信息的代码。你怎么能将这些重构为服务类C?答案 0 :(得分:0)
我会将构造函数添加到A和B,它接受C并相应地设置字段。与建议的解决方案相比,优势在于您的ExtensionServices不必了解基本字段。
答案 1 :(得分:0)
看起来您正在为Basic(和children)对象设置默认值。最好在他们的构造函数中做到这一点。
public class Basic
{
protected String foo;
// and other properties
public Basic()
{
foo = "some kind of foo";
// assign defaults to all other properties
}
}
public class SomeExtension extends Basic
{
protected string bar;
public SomeExtension()
{
super(); // set the default properties of the base class
bar = "some kind of bar";
}
}
请记住在子构造函数中调用super(),以便为继承的属性分配默认值。
public class BasicService
{
public Basic getBasic()
{
return new Basic();
}
}
public class ExtensionService extends BasicService
{
@Override
public Basic getBasic()
{
return new SomeExtension();
}
}
至少使用此结构,您无需在ExtensionService中实例化两个对象,并且实际上您没有在服务类中设置默认值。由于SomeExtension是Basic的子类,因此可以在声明返回类型为Basic的函数末尾返回SomeExtension。