Каков идиоматический способ наследования функциональности доступа к данным, а также свойств объекта? - PullRequest
0 голосов
/ 12 апреля 2010

Предположим, что следующее (слегка псевдокод для краткости):

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 голосов
/ 05 декабря 2012

Похоже, вы устанавливаете значения по умолчанию для ваших базовых (и дочерних) объектов. Вероятно, лучше сделать это в их конструкторах.

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, вы можете вернуть SomeExtension в конце функции, объявленный тип возвращаемого значения которой - Basic.

0 голосов
/ 15 апреля 2010

Я бы добавил конструктор к A и B, который принимает C и устанавливает поля соответственно.Преимущество перед вашим предлагаемым решением заключается в том, что ваши ExtensionServices не должны знать об основных полях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...