继承数据访问功能以及对象属性的惯用方法是什么?

时间:2010-04-12 13:32:15

标签: oop

假设以下(为了简洁起见,略为伪代码):

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?

2 个答案:

答案 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。