2012-01-05 2 views
4

Несколько ресурсов в моей системе используют концепцию коллекций объектов на основе коллекций Java.Объектно-ориентированный метод Bridge

Этот класс коллекции (абстрактный) обеспечивает базовую функциональность для другого конкретного класса, называемого списками, которые позволяют находить объекты через Индексы коллекции.

Я буду использовать в качестве примера свой класс HTTP-заголовков для объяснения.

У меня в своем конструкторе экземпляр этого класса классов. Каждое поле заголовка HTTP добавляется в коллекцию через метод Headers :: addHeader().

Очевидно, что у меня есть геттер метод, называемый getHeaders(), которые возвращают коллекции хранения, а не в коллекции объектов.

Итак, если мне нужно указать заголовок вне этого класса, мне просто нужно позвонить $ obj -> getHeaders(), и у меня есть ArrayObject со всеми добавленными объектами.

Хорошо!

Но в последнее время возникла необходимость использовать один из методов List, Списки :: find(), который находит объект, даже не знающий имя объекта или его конкретную позицию в хранилище коллекции.

Поскольку объект List находится в закрытом свойстве, Headers :: getHeaders() возвращает хранилище коллекций, и я не хочу нарушать инкапсуляцию, делая это свойство общедоступным, я не могу получить доступ к этому методу.

Все, что я код, помимо функциональности, должны быть зрительно изящным, и создать еще один метод получения, скажем, getHeadersLists() будет продуцируют вызов, как:

$obj -> getHeadersLists() -> find('foo'); 

Это некрасиво!

Итак, я быстро добавил __call() в заголовках класса и он работал отлично:

$obj -> find('foo'); 

Но кто-то я знаю (и он очень сведущим в Object Orientation теме) сказал мне, что это не так.

Мой аргумент был исключительно ориентирован на удобочитаемость, и он противопоставлял аргументы «в ориентации объектов, магических методах и читаемости не может сосуществовать».

И что? Что я должен сделать, чтобы создать этот «мост» между этими двумя классами, не используя _call() и сохраняя принципы ориентации объекта?

Я знаю, я мог бы вернуть объект коллекции в заголовках :: getHeaders() и использовать что-то вроде:

$obj -> getHeaders() -> find(); 

Но что-то я узнал об ориентации объектов ответственность. Ответственность этого метода, как сказано в заявлении, заключается в том, чтобы вернуть все Заголовки, а не внешний объект.

ответ

1

Я намерен поразить вас единственным принципом ответственности дяди Боба a.k.a (S.O.L.I.D большой S). Что вы можете прочитать в статье Principles Of OOD. Также для прямого ответа на ваш вопрос Tom Dalling's very nice article and example.

Single Responsibility Principle. Acknowledgement I have no rights or claims on this image.

Проблема при скрытии getHeaders вызова() функция, которая возвращает и объект типа списки то это выглядит, как вы вызываете объект и имеет функцию под названием находкой «, которые не должны иметь «поскольку это не его обязанность находить правильные заголовки.

Я могу понять ваш подход к ответственности.

Вы говорите: Когда я вызываю getHeaders(), я не должен принуждать к дальнейшему манипулированию результатом, чтобы получить то, что я хочу.

Это ваше предложение совершенно правильно. Но для достижения этого результата скрытие вызова функции getHeaders() с синтаксическим сахаром составляет совершенно неправильно. Потому что это собирается ввести меня в заблуждение.

Рассматривайте меня как третье лицо, читающее ваш код, я бы сразу предположил, что есть функция find() этого класса, которая очень вводит в заблуждение. Также я бы отклонил эту функцию find(), поскольку поиск из списка заголовков не предполагает ответственности от объекта, который является просто лишним дополнением или ошибкой. Итак, ваш коллега также прав: D.

Я Belive обстоятельства, заставляет вас называть находки(), чтобы иметь возможность использовать объект типа Заголовки виноват здесь.

Мое предложение для вашей дилеммы - это что-то вроде этого.

  1. Этот объект должен иметь определенную функцию, называемую getHeaders(). Не меняйте это. Он должен возвращать все заголовки.
  2. Сделайте второй funciton с именем getRelatedHeaders («foo») или getFooHeaders(), который вызывает getHeaders() внутри в инкапсулированном виде, чем использует find («foo») на них и возвращает ваши заголовки «foo».

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

Практически всегда, если вам нужно получить какое-либо свойство объекта и действовать на них. Затем вы также сможете инкапсулировать эту функциональность этому объекту/классу. Это почти всегда запах кода, когда вы получаете свойство объектов и используете его, чтобы что-то сделать, а затем вернуть его обратно.

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

Благодарим за ваше время, надеюсь, я вам кое-как помог: D.

0

Вот почему в PHP существует «защищенная» область, как и другие O.O. Языки программирования.

В случае, если вы знаете, «защищенный» член может получить доступ к классам потомков, но не может быть доступен как открытый.

В качестве предложения я обычно не использую «частный», но «защищенный» вместо этого по тем же причинам, что и ваш пост.

+0

+1 для этого же здесь. –

+1

Хорошо, но защищенная видимость в этом случае не поможет, потому что я не вызываю метод в контексте наследования. Подумайте так: Header ** использует ** Списки, а не Header ** - это ** Список. И, расширяя список, мой класс заголовков станет зависимым. –