2017-05-17 59 views
1

我目前正在學習將我的雜亂代碼拆分爲DDD(注意,學習)範例。實體(IEntityIUser)是域層由接口組成,然後在數據層(BaseEntityUser)實現。通過存儲庫模式訪問數據。但正如我所定義的IUserRepository返回IUser,在數據層我必須手動將它User回到IUser以匹配返回簽名。Kotlin繼承

我該如何避免鑄造?謝謝。

領域層

interface IEntity 
{ 
    var id: Long? 
    var name: String? 
} 

interface IUser : IEntity 
{ 
} 

interface IBaseRepository<T: IUser> 
{ 
    fun get(id: Long): Observable<T?> 
} 

interface IUserRepository : IBaseRepository<IUser> 
{ 
} 

數據層

abstract class BaseEntity() : IEntity 
{ 
    @SerializedName("id") 
    override var id: Long? = null 

    @SerializedName("full_name") 
    override var name: String? = null 
} 

class User() : BaseEntity(), IUser 
{ 
} 

interface UserRetrofitApi 
{ 
    @GET("user/{uuid}/") 
    fun get(id: Long): Observable<User?> 
} 

class UserRepository(private val _api: UserRetrofitApi) : IUserRepository 
{ 
    override fun get(id: Long): Observable<IUser?> { 
     return _api.get(id) as Observable<IUser?> // How to avoid casting here without resorting to generic UserRepository<T: IUser> 
    } 
} 
+1

UserRetrofitApi :: get有什麼特別的限制嗎?你只需要把它改成'fun get(id:Long):Observable '如果沒有的話。 – glee8e

+0

@ glee8e,看到我下面的回覆。 – DeuS

回答

1

聲明你get功能的基礎庫如下:

fun get(id: Long): Observable<out T?> 

,同樣改變get功能UserRepository到:

override fun get(id: Long): Observable<out IUser?> { 
    return _api.get(id) 
} 

更多信息請參見the docs on variance

+0

我讀過文檔,與第一次閱讀文檔相比,它有很大的意義。我已經嘗試過,它的工作原理。 後續問題是存儲庫需要支持CRUD操作,我不能聲明UserRepository是協變的。我已經閱讀了** use-site方差**和**類型投影**,但我無法解決我自己的問題,因爲我傳遞的是單個對象而不是對象的集合/數組。 – DeuS

0

如果我理解你的權利,你只需要改變你的UserRetroFitApi.get結果返回到Observable<IUser?>

class UserRetrofitApi 
{ 
    fun get(id: Long): Observable<IUser?> { 
     val user = User() 
     user.id = 1 
     user.name = "User 1" 
     return Observable.just(user) 
    } 
} 
+0

我正在使用[Retrofit](http://square.github.io/retrofit/)與服務器api進行交互。據我所知,Retrofit對象需要是一個具有默認構造函數的類,它有助於從json對象執行序列化和序列化。 我已更新示例代碼以反映實際的Retrofit界面。 – DeuS