代码整洁之道(五)---------------------数据结构与对象
来源:互联网 发布:更改位置定位软件 编辑:程序博客网 时间:2024/05/08 00:05
关于代码整洁方面,还想说的就是数据结构与对象,很多程序员对其概念不明,写代码的时候就颇为混乱。有时候将变量设置为私有(private),是不想将对象的变量公之于众,可是很多人又会自动的给该对象添加赋值器和取值器,那该私有变量与公共变量又有和区别?
想要弄明白对象与数据结构的区别,以及如何在写代码的时候正确运用,就先得弄明白数据抽象的概念。
(1)数据抽象
我们来先看两段代码,
代码一:
public class Point {
public double x;
public double y;
}
代码二:
public interface Point{
double getX();
double getY();
void setCartesiain(double x,double y);
double getR();
double getTheta();
void setPolar();
}
代码二的高明之处在于,你不知道该实现会是在一个矩形坐标系还是极坐标系中,可能两个都不是,它不仅明白无误的呈现出一种数据结构,那些方法固定了一套存取策略,可以单独读取某一坐标,但必须通过原子操作(指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束)赋值。
而代码一,你可以很明白他是在矩形坐标系中去实现,并要求我们单独操作那一个坐标,这就曝露实现,实际上,即便变量私有,我们用取值器与赋值器,仍然曝露了实现。
曝露实现并非只是在变量之间放上一个函数层那么简单,隐藏实现关乎抽象,类并不是简单的用取值器与赋值器将其变量向外推,而是曝露抽象接口,这样使用者无需了解数据的实现就可以操作数据的本体。
看看下面两段代码,想要知道现在定时器完成任务的状态,代码三通过具象的手段获得定时器的当前参数,而后者通过百分比抽象。
代码三:
public interface MyTimer{
double getStartTime();
double getEndTime();
double getCurrentTime();
}
代码四:
public interface MyTimer{
double getPercentOfCompletedTime();
}
如果我们不愿暴露数据细节,更愿意以抽象的形态表述数据。这不是简单的用接口和赋值器与取值器就万事大吉了,要如何呈现某个对象包含的数据,需要认真地思考,不要傻乐的添加赋值器与取值器,那是最坏的选择。
(2)数据、对象的互补
下面两个例子展示了对象与数据结构的差异。对象把数据隐藏在数据抽象之后,曝露数据操作的函数,数据结构曝露其数据,没有提供有意义的具体操作函数。他们是对立的这种差异貌似微小,但却有深远影响。
代码五:
class Square {
public double width;
public double height;
}
class Circle{
public double radius;
}
class Geometry{
public final double PI = 3.141592653589793;
public double area(Object shape) throws NoClassDefFoundError{
if(shape instanceof Square){
return ((Square) shape).height*((Square) shape).width
}else if(shape instanceof Circle){
return ((Circle) shape).radius*((Circle) shape).radius*PI;
}
throw new NoClassDefFoundError();
}
}
代码六:
interface Shape {
double area();
}
class Square implements Shape {
private double width;
private double height;
@Override
public double area() {
return width*height;
}
}
class Circle implements Shape{
private final double PI = 3.141592653589793;
private double radius;
@Override
public double area() {
return radius*radius*PI;
}
}
对于代码五。有人可能嘲笑它太过程化,而代码六是标准的面向对象的方案,area()是多态的,不需要Geometry类。所以再添加一个形状,现有函数一个都不会受影响,而当添加新函数时所有的形状都得改。二代码五去刚好相反,假如我想再添加一个去周长的函数,现有的形状类不会受到影响,但是添加一个新的形状就的修改方法area()。
我们可以看到这两种定义如此对立,这也说明了对象与数据结构的二分原理。所以面向对象难以做到的,面向过程式的代码就相对容易。
(3)混杂
著名的德墨忒尔定律(The Law Of Demeter)认为,模块不应该了解他所操作的对象的内部情况。也就是说,对象隐藏数据,曝露操作,尽量避免通过存储器曝露其内部结构。
有的时候我们会看到类似这样的代码,他就违反了德墨忒尔定律,
final String current_manager_name = MyApplication.getInstance().getCurrent_manger().getName();
这类代码常被称为火车失事。我们应该避免这样的代码。他混淆了数据结构与对象。
你要么把它改成:
final String current_manager_name = MyApplication.Current_manger.Name;
或者:
final String current_manager_name = new MyApplication.getCurrent_manger_Name();
有时候我们会用“豆”(bean)结构,注意,他算不上对象,只是一种数据结构。他的这种半封装形式只是一些纯面向对象者感觉舒服的一种假像。但不幸运的是,很多研发者在这类数据结构里塞很多业务规则方法,把这类数据结构当对象来用。这种混杂不属于整洁代码的范畴,解决方案就是在这种数据结构里添加一个对象,该对象包含处理业务逻辑的函数。
最后总结一下,对象曝露行为,隐藏数据。便于添加新的对象类型而无需修改既有的行为,同时也难以添加新的行为。数据结构曝露数据,没有明显的行为。便于向既有的数据结构添加新的行为,同时也难以添加新的数据结构。
- 代码整洁之道(五)---------------------数据结构与对象
- 代码整洁之道----对象和数据结构
- 代码整洁之道------ 对象和数据结构
- 代码整洁之道--对象和数据结构
- 代码整洁之道 对象和数据结构
- [读书笔记] 代码整洁之道(五)
- 代码整洁之道读书笔记(五)
- 《代码整洁之道》摘录---对象和数据结构
- 6、代码整洁之道——对象和数据结构
- 代码整洁之道读书笔记--对象和数据结构
- 代码整洁之道--对象和数据结构体会
- 【《代码整洁之道》精读与演绎】之五 整洁类的书写准则
- 【《代码整洁之道》精读与演绎】之五 整洁类的书写准则
- 【《代码整洁之道》精读与演绎】之五 整洁类的书写准则
- 【《代码整洁之道》精读与演绎】之五 整洁类的书写准则
- 【《代码整洁之道》精读与演绎】之五 整洁类的书写准则
- 代码整洁之道精华——第六章 对象和数据结构
- 代码整洁之道-第六章-对象和数据结构-page87
- shell脚本编程流水笔记
- ROS下创建meta_package
- Linux下DIR,dirent,stat等结构体详解
- Nginx (一) 基础入门
- nyoj 36 最长公共子序列【lcs&&dp】
- 代码整洁之道(五)---------------------数据结构与对象
- 安装fedora后要安装的软件
- 小模板蕴含大道理
- char * const cp | const char * p | char const * p 区别
- 友盟社会化Android组件之第三方登录
- ActionBar的TabListener与Fragment
- Android Launcher开发(二)AppWidget(桌面小部件)解析
- ServletContextListener,各种获取servletContext对象的方法
- JAVA通过JDBC连接MySQL数据库提示连接拒绝问题处理