Позволение установщику установить значение свойства, принадлежащего другому классу

Должен ли установщик всегда устанавливать значения своих прямых свойств, а не свойств связанных объектов? Например, у меня есть что-то вроде ниже, где клиент API принимает XML:

Class XML {
private $value;

// Setter for $value exists here
...
}

Class Client {
private $xml; // XML
public function __construct(XML $xml)
{
$this->xml = $xml;
...
}
}

Я хочу $value модифицировано после Client создается, потому что, скажем, я хочу изменить или добавить некоторые параметры в запрос. Должен ли я использовать сеттер в XML и восстановить экземпляр Client при изменении запросов, или иметь установщик в Client непосредственно, так что мне не нужно заново создавать Client?

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

0

Решение

Обычно, если у класса есть публичные методы, они предназначены для доступа. Таким образом, вы можете подумать, без вреда при их использовании.

Тем не менее, спросите себя: почему класс имеет в первую очередь методы получения / установки? Средства доступа обычно находятся в классах для объектов данных. Основная цель таких объектов — нести данные, они обычно не делать что угодно — в отличие, например, от службы или класса контроллера.

Следующий вопрос: для чего нужен конструктор? Конструктор используется для установки внутреннего состояния объекта, и для этого потребуется зависимости в качестве параметров. В духе слабой связи зависимости не должны быть изменяемыми от других классов.

Глядя на ваш код, я предполагаю, что вы пишете какое-то клиентское приложение на основе XML, и вы хотите Client класс зависеть от экземпляра XML учебный класс.

Изменение внутреннего состояния XML объект из Client это плохая идея. Другие классы, зависящие от этого экземпляра, не будут знать о модификации и, возможно, получат неожиданные результаты.

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

1) Если вам нужно установить значение только для контекста одного вызова метода XML, измените метод, чтобы принять $value в качестве параметра. Но не устанавливайте его как член объекта внутри XML!

class XML
{
public function doSomething($value)
{
…

// do whatever you need with $value,
// but do *not* do something like $this->value = $value
}
}

2) Если взаимодействие с $value должно быть согласованным для нескольких операций, вы должны извлечь эти операции из XML в собственный класс работника или объекта данных. XML должен иметь метод фабрики для создания экземпляра этого вспомогательного класса. Тогда либо XML или же Client может иметь методы для использования работника:

class XML
{
public function createWorker($value)
{
return new XmlWorker($value, $this);

// XmlWorker might even contain a reference to the XML instance, e.g.
return new XmlWorker($value, $this);
}

public function doSomethingWithWorker(XmlWorker $worker)
{
$value = $worker->getValue();
$worker->doWork();
}
}

class Client
{
private function doSomething()
{
$worker = $this->xml->createWorker($value);
$worker->doWork();
}
}

Я бы порекомендовал прочитать Шаблоны проектирования; в этом контексте особенно о свободном сцеплении & Разделение проблем, заводские методы и внедрение зависимостей.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]