Код, Завершенный 2ed, состав и делегация

После нескольких недель, читая на этом форуме я думал, что пришло время для меня сделать мое первое сообщение.

Я в настоящее время перечитываю Завершенный Код. Я думаю, что это - 15 лет с прошлого раза, и я нахожу, что все еще не могу написать код ;-)

Так или иначе на странице 138 в Коде, Завершенном, Вы находите этот пример ужаса кодирования. (Я удалил часть кода),

class Emplyee {
public: 
 FullName GetName() const;
 Address GetAddress() const;
 PhoneNumber GetWorkPhone() const;
 ...

 bool IsZipCodeValid( Address address);
 ...

private: 
   ...
}

То, что думает Steve, плохо, то, что функции свободно связаны. Или он имеет, пишет, что "нет никакого логического соединения между сотрудниками и стандартными программами, которые проверяют почтовые индексы, номера телефона или классификации заданий"

Хорошо я полностью соглашаюсь с ним. Возможно, что-то как ниже примера лучше.

class ZipCode
{
public:
 bool IsValid() const;
    ...
}

class Address {
public:
   ZipCode GetZipCode() const;
   ...
}

class Employee {
public: 
 Address GetAddress() const;
    ...
}

При проверке, допустима ли zip, необходимо было бы сделать что-то вроде этого.

employee.GetAddress().GetZipCode().IsValid();

И это не хорошо относительно к Закону Demeter.

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

class ZipCode
{
public:
 bool IsValid();
}

class Address {
public:
   ZipCode GetZipCode() const;
   bool IsZipCodeValid() {return GetZipCode()->IsValid());
}

class Employee {
public: 
 FullName GetName() const;
 Address GetAddress() const;
 bool IsZipCodeValid() {return GetAddress()->IsZipCodeValid());
 PhoneNumber GetWorkPhone() const;
}

employee.IsZipCodeValid();

Но с другой стороны у Вас есть стандартные программы, который не имеет никакого логического соединения.

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

5
задан Kara 5 September 2013 в 00:07
поделиться

3 ответа

Это платите сейчас, а платите позже.

Вы можете написать функции делегирования и оболочки заранее (заплатите сейчас), а потом у вас будет меньше работы, изменяя внутренности employee.IsZipCodeValid (). Или вы можете перейти к IsZipCodeValid, написав

employee.GetAddress().GetZipCode().IsValid();
везде, где вам это нужно в коде, но заплатите позже, если вы решите изменить дизайн своего класса таким образом, чтобы этот код нарушался.

Вы можете выбрать свой яд. ;)

1
ответ дан 14 December 2019 в 04:35
поделиться

Вам не хватает логического соединения:

class ZipCode
{
public:
 bool IsValid();
}

class Address {
public:
   ZipCode GetZipCode() const;
   bool IsAddressValid();
   bool IsValid() {return GetZipCode()->IsValid() && IsAddressValid());
}

class Employee {
public: 
 FullName GetName() const;
 Address GetAddress() const;
 bool IsEmployeeValid();
 bool IsValid() {return GetAddress()->IseValid() && IsEmployeeValid());
 PhoneNumber GetWorkPhone() const;
}

employee.IsValid();
7
ответ дан 14 December 2019 в 04:35
поделиться

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

class Address
{
    public:
        static IsZipValid(ZipCode zip) { return zip.isValid(); }
};

Затем вы делаете

Address::IsZipValid(employee.GetAddress().GetZipCode());

Я думаю, что это удовлетворительно в соответствии с вашими ограничениями логической ассоциации и закона Деметры.

0
ответ дан 14 December 2019 в 04:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: