2013-10-25 65 views
0

我目前正在使用的遺留Java代碼庫使用了一個臭名昭着的框架。它爲我提供了很好的包裝罐子中的開箱即用領域類。域類不過是獲取者和設置者的包。打包域類中的豐富域

這是通過從靜態的Util類中提取程序代碼到適當的地方,即域類本身,來防止繁殖豐富的域模型。例如,考慮的邏輯如下方法中:

public static boolean areFriends(User user1, User user2) { 
    for (User friend : user1.getFriends()) { 
     if (friend.equals(user2)) { 
      return true; 
     } 
    } 
    return false; 
} 

這可以替代地被很好地表達爲UserisFriendOf(User another)。然而,User類全部被鎖定。順便說一句,框架使用的生命週期方法在User對象傳遞:

//Life-cycle method 
public void execute(FrameworkBlob frameworFattyObject) { 
    ... 
    User user = frameworFattyObject.getUser(); 
    User loggedInUser = getLoggedInUserFromSomewhere(); 
    bool areFriends = BadUtilClass.areFriends(user, loggedInUser); 
    ... 
} 

牢記可測試性,是有辦法,我可以這樣說:

bool areFriends = user.isFriendOf(loggedInUser); 
+1

我假設您無法以任何方式訪問您的描述中的原始代碼。是否有可能影響創建用戶對象的代碼?如果是這樣,您可以在添加所需代碼的新類中繼承User類的子類。 – DanielBarbarian

+0

另一種選擇是將靜態類更改爲普通類並提取接口並使接口上的執行方法生效。這會提高可測性。 –

+0

@DanielBarbarian我喜歡子分類的想法,但不幸的是我沒有發言權在框架創建User對象的方式和位置。 – aquaraga

回答

1

不熟悉臭名昭着的框架。我應該先評論一下,但這太長了。

是否有可能向生命週期方法注入某些東西?

例如:

public class AClassIDontKnow { 

    private DomainModelMapper mapper;//inject this 
    //Life-cycle method 
    public void execute(FrameworkBlob frameworFattyObject) { 
     ... 
     UserDomainModel user = mapper.getUser(frameworFattyObject); 
     UserDomainModel loggedInUser = getLoggedInUserFromSomewhere(); 
     bool areFriends = user.isFriendOf(loggedInUser); 
     ... 
    } 
} 

public class DomainModelMapper { 
    UserDomainModel getUser(FrameworkBlob frameworFattyObject) { 
     User userAnemicModel = frameworFattyObject.getUser(); 
     //map the anemicModel to a rich domain model 
     return ....; 
    } 
} 

因此,測試策略:
1)DomainModelMapperUnitTest放置測試的映射。
2)UserDomainModelUnitTest包含isFriend(用戶)
3)如果需要,在AClassIDontKnowUnitTest中使用mock for DomainModelMapper。

+0

我喜歡這種方法!除了映射器中的咕嚕聲。 – aquaraga

+0

@aquaraga生命週期方法的目的是什麼?哪一層通過FrameworkBlob?你能發表一個如何調用execute方法的例子嗎? – Hippoom