在開發(fā)中竟块,我們經(jīng)常會把變量設(shè)置為私有(private)壶运,不想使用者依賴這些變量耐齐,但很多程序員也會給對象自動添加get/set方法,將私有變量公之于眾蒋情。
具體點(diǎn)
public class User {
private int userId;
private String userName;
}
抽象點(diǎn)
public interface User {
int getUserId();
String getUserName();
void setUser(int userId, String userName);
}
抽象點(diǎn)優(yōu)勢在于使用者不知道該User信息是如何實(shí)現(xiàn)的埠况,并明白無誤地呈現(xiàn)了一種數(shù)據(jù)結(jié)構(gòu);而具體點(diǎn)暴露了具體實(shí)現(xiàn)棵癣,即便是私有變量辕翰,通過get/set還是會暴露具體實(shí)現(xiàn)。
所以隱藏實(shí)現(xiàn)不是單單的把變量之間放上一個函數(shù)層那么簡單狈谊。隱藏實(shí)現(xiàn)關(guān)乎于抽象喜命,類并不簡單地用get/set將變量推向外間沟沙,而是暴露抽象接口,以便使用者無需了解數(shù)據(jù)的實(shí)現(xiàn)就能操作數(shù)據(jù)本地壁榕。
當(dāng)然在具體實(shí)現(xiàn)中矛紫,這種并不是絕對的,對象和數(shù)據(jù)結(jié)構(gòu)有相關(guān)的反對稱性牌里。
過程式代碼
public class PercentDiscount {
private float percent;
private float price;
}
public class ReductionDiscount {
private float reduction;
private float price;
}
public class Discount {
public float getPrice(Object obj) throws NoSuchFieldException {
if (obj instanceof PercentDiscount) {
PercentDiscount pd = new PercentDiscount();
return pd.percent * pd.price;
} else if (obj instanceof ReductionDiscount) {
ReductionDiscount rd = new ReductionDiscount();
return rd.price - rd.reduction;
} else {
throw new NoSuchFieldException();
}
}
}
多態(tài)式代碼
public class PercentDiscount implements Discount {
private float percent;
private float price;
@Override
public float getPrice() {
return price * percent;
}
}
public class ReductionDiscount implements Discount {
private float reduction;
private float price;
@Override
public float getPrice() {
return price - reduction;
}
}
public interface Discount {
float getPrice();
}
我們看到這兩種定義的本質(zhì)是截然對立的颊咬。過程式代碼便于在不改動既有數(shù)據(jù)結(jié)構(gòu)的前提下添加新函數(shù),而面向?qū)ο蟠a便于在不改動既有的函數(shù)下添加新類牡辽。
所以在具體的業(yè)務(wù)場景在來決定使用哪種方式喳篇,需要添加新數(shù)據(jù)類型而不是新函數(shù)的時候可以使用面向?qū)ο螅恍枰砑有潞瘮?shù)而不是數(shù)據(jù)類型使用過程式比較合適态辛。一切都是對象只是一個傳說麸澜。具體的使用方式需要根據(jù)當(dāng)前業(yè)務(wù)場景來決定。