添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

本文源于Google公司的马桶上的健康代码,作者:Marc Eaddy

编程语言会提供在很多上下文下有用的一些基本类型,如:integers, strings, 及maps. 比如:一个string可用于保存从个人名字到网页URL的所有内容。 但是, 如果过于依赖基本类型而不是自定义抽象的代码可能很难理解和维护

基本类型偏执是指过度使用基本类型来代表更高级别的概念 。 如下代码所示的使用基本类型来表示形状:

vector<pair<int, int>> polygon = ...
pair<pair<int, int>, pair<int, int>> bounding_box = GetBoundingBox(polygon);
int area = (bounding_box.second.first  - bounding_box.first.first) *
           (bounding_box.second.second - bounding_box.first.second);

pair不是正确的抽象级别,因为在一种情况下,其通用名称的first字段和second字段用于表示X和Y,左下角(左上角?)和右上角(右下角? )。 更糟糕的是,基本类型不会封装领域特定代码,如:计算边长和面积。

使用更高级别的抽象替换基本类型可以产生更清晰,封装性更好的代码:

Polygon polygon = ...
int area = polygon.GetBoundingBox().GetArea();

这里还有些其他基本类型偏执的示例:

  • 通过将值合并到自定义的更高层次的抽象中,可以轻松将相关的maps, lists, vectors等组合到单个集合中。
  • // 反例
    map<UserId, string> id_to_name;
    map<UserId, int> id_to_age;
    
    // 正例
    map<UserId, Person> id_to_person;
      
  • 具有魔法索引/键的vector或map,例如 索引/键以0、1和2的字符串值分别保存名称,地址和电话号码。 替之以合并这些值成为更高级别的抽象。
  • // 反例
    person_data[kName] = "Foo";
    
    // 正例
    person.SetName("Foo");
      
  • 包含复杂或结构化文本(例如日期)的字符串。 替之以提供自文档访问器(例如GetMonth)并保证正确性的更高级别的抽象(例如Date)。
  • // 反例
    string date = "01-02-03";
    
    // 正例
    Date date(Month::Feb, Day(1), Year(2003));
      
  • 存储时间值的整数或浮点数,例如:秒。 替之以结构化的timestamp或duration类型。
  • // 反例
    int timeout_secs = 5;
    
    // 正例
    Duration timeout = Seconds(5);
    

    从简单的int到复杂的红黑树,任何类型都可能太原始而无法完成工作。 如果你看到使用很多基本类型的代码,而这些基本类型可以通过使用更高级别的抽象来进行更清晰或更准确的封装,请对其进行重构或有礼貌地提醒作者使其类化