一、數據、對象的反對稱性
對象:將數據隱藏于抽象之后,暴露操作數據的函數。
數據結構:暴露數據本身,不提供有意義的函數。
例如下面:
public class Point {
public double x;
public double y;
}
public interface Point {
double getX();
double getY();
void setCartsian(double x,double y);
double getR();
double getTheta();
void setPolar(double r,double theta);
}
一個暴露了實現,一個完全隱藏了實現。但是該接口還是呈現了一種數據結構。隱藏實現并非只是在變量之上加一層函數層。隱藏實現關乎抽象!類并不是簡單用存儲器和賦值器,而是暴露抽象接口嗎,讓用戶無須了解數據的實現就能操作數據<b>本體</b>。
public interface Vehicle {
double getFuelTankCapacityInGallons();
double getGallonsOfGasoline();
}
public interface Vehicle {
double getPercentFuelRemaining();
}
以上兩段代碼以后者為佳。我們不愿暴露數據細節,更愿意以抽象的形態表述數據。<b>不要亂加取值器和賦值器,那是最壞的選擇。</b>
<b>過程式(使用數據結構的代碼)便于在不改動既有數據結構的前提下添加新函數。面向對象代碼便于在不改動既有函數的前提下添加新類。</b>
反過來講也說得通:
<b>過程是代碼難以添加新的數據結構,因為必須修改所有函數;面向對象代碼難以添加新函數,因為必須修改所有類。</b>
結論:一切對象都是傳說,有時候必須做一些過程式的操作。
二、得墨忒耳律
The Law of Demeter:模塊不應了解它操作對象的內部情形。更準確地說,它認為類C的方法f只應該調用以下對象的方法:
- C
- 由f創建的對象;
- 作為參數傳遞給f的對象;
- 由C實體變量持有的對象。
方法不應該調用任何函數返回對象的方法,除非返回的是數據結構。即智能與朋友聊天,而與陌生人敬而遠之。
三、數據傳送對象
最為精煉的數據結構是只包含公有變量、沒有函數的類。這種結構有時被稱為數據傳送對象,DTO(Data Transfer Objects)。DTO是非常有用的結構,尤其是在與數據庫通信、或者套接字傳遞消息。更常見的是bean類的結構。豆結構擁有自否賦值器和取值器操作私有變量。這種半封裝會顯得更OO,當時通常沒有任何好處。