繁体   English   中英

代码完成2ed,组成和委托

[英]Code Complete 2ed, composition and delegation

在这个论坛上看了几个星期后,我觉得是时候做我的第一篇文章。

我目前正在重读Code Complete。 我认为这是自上次以来的15年,我发现我仍然无法编写代码;-)

无论如何,在Code Complete的第138页,你会发现这个编码恐怖的例子。 (我删除了一些代码)

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

但是,你再次拥有没有逻辑连接的例程。

我个人认为这篇文章中的所有三个例子都很糟糕。 这是我没想过的其他方式吗?

您缺少逻辑连接:

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

这是现在支付与后期支付。

您可以预先编写委托和包装函数(立即付款),然后更少的工作更改employee.IsZipCodeValid()的内部。 或者,您可以通过写入隧道传输到IsZipCodeValid

employee.GetAddress().GetZipCode().IsValid();
您需要在代码中的任何地方,但如果您决定以破坏此代码的方式更改您的类设计,请稍后付款。

你可以选择你的毒药。 ;)

由于Employee类和zip-code验证之间没有逻辑连接,因此您可以将Zip代码验证放入更符合逻辑的Address类中。 然后,您可以要求Address类为您验证Zip代码。

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

然后你做

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

我认为在你的逻辑关联和德米特定律的约束下,这是令人满意的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM