2017-05-17 16 views
1

私は現在、乱雑なコードをDDD(ノート、学習)のパラダイムに分割することを学んでいます。エンティティ(IEntity,IUser)はドメイン層であり、データ層(BaseEntity,User)で実装されています。データへのアクセスは、リポジトリパターンによるものです。しかし、IUserRepositoryIUserに返すように定義した場合、返信の署名と一致するように、データレイヤーでUserIUserに手動でキャストする必要があります。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?> 

と同様にしUserRepositoryget機能を変更します。

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

詳細についてはthe docs on varianceを参照してください。

+0

私はこの文書を読んだことがあります。初めて読んだときと比べるとかなり意味があります。私はそれを試して、それが動作します。 フォローアップの質問は、リポジトリがCRUD操作をサポートする必要があり、 'UserRepository'が共変であると宣言することができないということです。 ** use-site variance **と** type projections **を読んだことがありますが、与えられた例のように、オブジェクトのコレクション/配列ではなく単一のオブジェクトを渡しているので、私自身の質問を解決することはできません。 – DeuS

0

私は右のあなたを理解していれば、あなたはちょうどあなたがObservable<IUser?>UserRetroFitApi.getの結果を返す変更する必要があります。

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