Clean Code Part2

对象与数据结构

首先让我们进行一个严肃的思考,对象与数据结构的区别在哪里?

如下两段代码分别用数据结构和对象的方法来描述了一个Point。

    public class Point {
private double x;
public double y;
}
    public interface Point {
double getX();
double getY();
void setCartesian(double x,double y);
double getR();
double getTheta();
void setPolar(double r,double theta);
}

可以看到,数据结构表达的是实现:Point这个事物由x和y来组成。

而对象只是表达了"怎么用"这个主题。无需了解数据的实现就能操作数据的本体,是对象最大的区别。

过程式与面向对象

那么,围绕数据结构和对象,我们代码实现会有什么不同么?

下面分别是使用数据结构和对象,实现了面积计算这个功能。

    public class Square {
public Point topLeft;
public double side;
}
public class Rectangle {
public Point topLeft;
public double height;
public double width;
}
public class Circle {
public Point center;
public double radius;
}
public class Geometry {
public final double PI = 3.141592653589793;
public double area(Object shape) throws NoSuchShapeException {
if ( shape instanceof Square) {
Square s = (Square) shape;
return s.side * s.side;
}
else if ( shape instanceof Rectangle ) {
Rectangle r = (Rectangle) shape;
return r.height * r.width;
}
else if ( shape instanceof Circle) {
Circle c = (Circle) shape;
return PI * c.radius * c.radius;
}
throw new NoSuchShapeException();
}
}
    public class Square implements Shape {
private Point topLeft;
private double side;
public double area() {
return side * side;
}
}
public class Rectangle implements Shape {
private Point topLeft;
private double height;
private double width;
public double area() {
return height * width;
}
}
public class Circle implements Shape {
private Point center;
private double radius;
public final double PI = 3.141592653589793;
public double area() {
return PI * radius * radius;
}
}

可以认为,面向过程是基于数据结构的开发,而面向对象是基于对象的开发。

它们其实是互有优劣:

过程式代码便于在不改动数据结构的前提下添加新函数。

面向对象便于在不改动既有函数的前提下添加新类。

在实际使用中,我们要根据使用场景来进行选择。一切都是对象,只是一个传说。

迪米特法则

下面讨论下面向对象的一个重要原则:迪米特法则。

法则的定义是:模块不应了解它所操作对象的内部情况。最小知识原则。

talk only to your immediate friends

具体来说,类C的方法f只应调用一下对象的方法:

1.C

2.由f创建的对象

public void a(){
A a = new A();
a.do();
}

3.作为参数传递给f的对象

4.由C的实体变量持有的对象

class C {
private A a;
public void f(){
a.do();
}
}

个人觉得,对于迪米特法则的运用,更重要的是要弄清楚,这个法则主要是希望禁止什么操作。

主要是:方法不应调用任何函数返回对象的方法。只和朋友谈话,不与陌生人谈话。

典型的是下面这种链式的调用,方法返回对象,然后继续调用返回对象的方法。这类代码常被称为"火车失事"。

  final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();

如何避免火车失事呢,我们可以采用facade(门面)模式,对代码进行封装。

   BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);

那如果方法存在排列组合的调用情况,facade模式无法表述呢,这个时候有一个折衷的方法,就是装饰模式。

 class Num {
public Num add(int a){
...
return this;
}
}

小结

对象和数据结构是对事物的两种表达方法,对象关注"怎么用",数据结构关注"是什么"。

相对应的,过程式代码便于在不改动数据结构的前提下添加新函数。面向对象便于在不改动既有函数的前提下添加新类。

迪米特法则主要希望禁止"火车失事"的链式调用,我们可以用facade模式来重构代码,如无法避免链式调用,也应用装饰模式来实现。

小课堂week13 Clean Code Part2的更多相关文章

  1. 小课堂Week12 Clean Code Part1

    小课堂Week12 Clean Code Part1 今天的主题是函数,让我们看一个函数,找一找其中的"不整洁". 我们也根据这段代码,讨论下对于整洁代码的两个重要原则. publ ...

  2. 小课堂Week9 例外处理设计的逆袭Part2

    小课堂Week9 例外处理设计的逆袭Part2 今天继续阅读<例外处理设计的逆袭>这本书,我们先看两个案例: 案例1 问:如果要设计一个依据学号到数据库中查询学生资料的函数,当找不到符合条 ...

  3. 说说怎么写clean code

    前两天参加了公司组织的一个培训,主题是“如何写出好的代码” ,刚看到这个主题,第一反应是又不知道是哪个培训机构来忽悠钱的!老大安排了,就去听听呗. 说实在的,课程内容没有什么新鲜的东西,就是讲讲如何发 ...

  4. 小课堂Week10 例外处理设计的逆袭Part3

    小课堂Week10 例外处理设计的逆袭Part3 今天是<例外处理设计的逆袭>这本书阅读的第三天,也是最后一天,我们会主要通过实例,对Part2中提出的例外处理等级进行解读. Level1 ...

  5. Spark小课堂Week5 Scala初探

    Spark小课堂Week5 Scala初探 Scala是java威力加强版. 对Java的改进 这里会结合StreamingContext.scala这个代码说明下对Java的改进方面. 方便测试方式 ...

  6. 《Clean Code》 代码简洁之道

    作者介绍 原文作者: Robert C. Martin, Object Mentor公司总裁,面向对象设计.模式.UML.敏捷方法学和极限编程领域的资深顾问,是<敏捷软件开发:原则.模式.与实践 ...

  7. 聊聊clean code

    clean code,顾名思义就是整洁的代码,或者说清晰.漂亮的代码,相信大多数工程师都希望自己能写出这样的代码. 也许这是个千人千面的话题,每个工程师都有自己的理解.比如我,从一个天天被骂代码写得烂 ...

  8. Clean Code之JavaScript代码示例

    译者按: 简洁的代码可以避免写出过多的BUG. 原文: JavaScript Clean Code - Best Practices 译者: Fundebug 本文采用意译,版权归原作者所有 引文 作 ...

  9. 【笔记】Clean Code(持续更新)

    这个暑假出来实习,第一次体会到在一个团队中开发的体验,与网上的网站看到的大为不同,以前看网上说什么程序员写了屎山代码,写了一堆模糊的注释或者说垃圾代码不写注释. 但在我的实习体验中,代码虽然看起来很多 ...

随机推荐

  1. 菜鸟-手把手教你把Acegi应用到实际项目中(11)-切换用户

    在某些应用场合中,我们可能需要用到切换用户的功能,从而以另一用户的身份进行相关操作.这一点类似于在Linux系统中,用su命令切换到另一用户进行相关操作.      既然实际应用中有这种场合,那么我们 ...

  2. Redis主从是否生效的特殊测试方法

    Redis主从的特殊测试方法 配置主从 Redis的主从设定,相较于MySQL的主从,配置起来非常简单,不必像MySQL数据库一样手动记录bin log的位置再配置,但又可以像MySQL一样,一主带多 ...

  3. canvas-a10isPointPath2.html

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 初学cocos2dx-3.x之使用Scale9Sprite时的配置问题

    今天学习的时候遇到了Scale9Sprite————一张可拉伸的精灵,只要给它设置一下大小,它就会自动拉伸. Scale9Sprite* nineGirl = Scale9Sprite::create ...

  5. Windows 消息机制

    Windows 是一个消息驱动的操作系统.一个消息由一个消息名称(UINT 类型)和两个参数(WPARAM,LPARAM)构成.当用户进行了输入或是窗口的状态发生改变时,系统会发送消息到某一个窗口.例 ...

  6. APP完整的启动流程

    0.加载+load方法 1.执行Main函数 2.执行UIApplicationMain函数. 3.创建UIApplication对象,并设置UIApplicationMain对象的代理.UIAppl ...

  7. 学习总结 java 创建及其练习

    创建: 打开eclipse—文件—新建—java项目—项目名称命名—点击texe-1练习下拉箭头—右击src—新建—类—设置类名称(名称设置时不要添加空格),在“想要创建哪些方法跟”下面点击:publ ...

  8. 洛谷P2723 丑数 Humble Numbers

    P2723 丑数 Humble Numbers 52通过 138提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交  讨论  题解 最新讨论 暂时没有讨论 题目背景 对于一给定的素数 ...

  9. java(POI):基于模版的Excel导出功能,局部列写保护总结

    需求描述: 1.导出的Excel中部分列包含有下拉列表,并没有尝试过用代码实现这种功能,个人感觉比较棘手,故采用了模版的形式,直接导出数据到已经创建好的Excel模版中 2.Excel的第一列需要写保 ...

  10. 可视化日志分析工具Gltail的安装与使用

    可视化日志分析工具Gltail的安装与使用      GlTail.rb 是一款带有浓郁的 Geek 风格的可视化日志分析工具,它采用 Ruby 技术构建,并利用 OpenGL 图形技术进行渲染,呈现 ...