Создание объекта на основе подклассов двух других объектов - PullRequest
0 голосов
/ 11 июня 2018

Моя проблема дизайна заключается в следующем.

У меня есть два класса, каждый с количеством подклассов.У меня есть фабрика, которая должна создать объект на основе подкласса каждого из этих объектов.

Это проблема аутентификации.Фабрика генерирует объект правила на основе типа человека и типа ресурса, к которому они хотят получить доступ.Правило имеет подклассы AlwaysAllow, NeverAllow и timeBasedAllow.С потенциалом большего, если в будущем потребуется более сложная система доступа.

Таким образом, в идеале в будущем можно было бы создать нового человека с новым подклассом, новым ресурсом с новым подклассом.Параметры, по которым определяется доступ, могут быть изменены с помощью нового подкласса правил, а конкретный доступ для каждого типа человека и типа комнаты может быть изменен в рамках фабрики правил.

Пока что единственный способ, которым я могу думать, это сделать перечисление внутри подклассов, что лишает смысла, потому что тогда добавление нового человека или комнаты требует нового класса и изменения в классе перечислениячто выглядит грязно.

Я также очень хочу держать данные и логику раздельно, поэтому я не могу просто переместить методы аутентификации в класс person, потому что это потребует от класса person знать, сколько там типов комнатбыли, что определенно не идеально.

Возможно, я стремлюсь к чему-то, что нереально достижимо, но я не могу избавиться от ощущения, что у меня есть хорошее чистое решение.

Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 11 июня 2018

Название вашего вопроса звучит так, как будто вы ищете множественное наследование, что не разрешено в Java.В отличие от C ++, класс может extend один и только один класс.Тем не менее, Java также имеет interface, что, я подозреваю, может быть тем, что вы ищете.

Класс interface не может быть создан и может иметь абстрактные методы.Конкретный класс может implement столько интерфейсов, сколько необходимо, и конкретный класс должен реализовывать каждый абстрактный метод, объявленный интерфейсом.Абстрактные классы также могут реализовывать интерфейсы, а абстрактные методы, которые они не реализуют, должны быть реализованы конкретными классами, расширяющими их.

Я предлагаю извлечь ваши методы аутентификации в interface, возможно, называемый AuthRule или что-то подобное.AuthRule может иметь абстрактные методы с аутентификацией для представления без предоставления точного стиля, используемого для аутентификации.Таким образом, вы реализуете AlwaysAllow implements AuthRule, и тогда методы authenticate в AlwaysAllow всегда будут возвращать true.

Однако, во-вторых, вы, похоже, пытаетесь использовать наследование когда композиция лучше подойдет вашим потребностям.Теперь, когда у вас есть Person наследует его правило аутентификации, вместо этого правило должно быть полем члена внутри Person.Так, например:

class Person extends User {
  AuthRule rule;
  Person(AuthRule myrule) {
    rule = myrule;
  }

  bool authenticate(...) {
    return rule.authenticate(...);
  }
}

Если вы следуете шаблону проектирования, основанному на внедрении объектов в другие объекты для смешивания необходимых вам функций, ваш код станет намного более удобным и расширяемым.Надеюсь, это поможет вашей проблеме.

...