Вопрос

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

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

В любом случае, на странице 138 в Code Complete вы найдете этот ужасный пример кодирования.(Я удалил часть кода)

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

 bool IsZipCodeValid( Address address);
 ...

private: 
   ...
}

Что Стив считает плохим, так это то, что функции слабо связаны между собой.Или он пишет: «Нет логической связи между сотрудниками и процедурами проверки почтовых индексов, номеров телефонов или классификаций должностей»

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

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

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

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

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

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

А это нехорошо с точки зрения Закон Деметры.

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

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();

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

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

Это было полезно?

Решение

Это зарплата сейчас противОплатить позже.

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

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

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

Другие советы

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

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();

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

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

Тогда ты делаешь

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top