90844


Kotlin、Mybatisの実装で相談です。  
RepositoryからMapperにオブジェクトを渡すときに、Entity→Dtoに変換する必要があるんですがロジックはどこに書けばいいんでしょうか？

Dtoに `toEntity` というメソッドを持たせているので、Mapper→Repositoryに値を返すときは dto.toEntity
という処理にしています。

Entityにも `toDto` みたいなメソッドを持たせようか悩んだんですが、Entityにロジックを持たせることが正解かわからず悩んでいます。

[code]

    interface Mapper {
       @Insert("省略")
       fun create(dto: Dto)
    }
    
    open class Repository(private val mapper:Mapper) {
     fun create(entity: Entity) {
            mapper.create(entity)// ここの処理で悩んでいます
        }
    }
    
[/code]


CC BY-SA 4.0
2022-08-30T07:51:34.777
90835
2022-08-30T15:55:14.973
30328
question
java spring spring-boot kotlin java8
Entity→DTOに変換するロジック


これが唯一の解でそれ以外は全て誤り、というようなものは存在しないですが、その中でもポピュラーであろうと思われる考え方を示します。

* * *

依存関係の方向を考えてみます。  
いま、

[code]

    class Dto(...) {
        fun toEntity(): Entity {...}
    }
    
[/code]

という関数を実装しているので、依存関係は次のようになっています:  
[![画像の説明をここに入力](https://i.stack.imgur.com/woeDR.png)](https://i.stack.imgur.com/woeDR.png)  
(`Dto` が `Entity` に依存している)

ここに、

[code]

    class Entity(...) {
        fun toDto(): Dto {...}
    }
    
[/code]

というような関数を用意してしまうと、お互いが他方に依存する関係になってしまいます:  
[![画像の説明をここに入力](https://i.stack.imgur.com/Guu6x.png)](https://i.stack.imgur.com/Guu6x.png)

一般的に相互依存は避けるべき形です。

では、依存関係を片方向に留めるとして、どちらがどちらに依存するのが適切かを考えてみます。

  * `Entity` は `Dto` が無くても存続できる必要があるでしょう。
  * `Dto` は `Entity` から変換されるものなので、 `Entity` ありきの存在でしょう。つまり、 `Entity` への依存は許容できるでしょう。

つまり、冒頭の図で示した依存関係  
![1](https://i.stack.imgur.com/woeDR.png)  
を保つのが妥当、ということです。

これを実現する手段のうちのひとつとして、 `Dto` の companion object で変換関数を実装する、というものが挙げられます:

[code]

    class Dto(...) {
        fun toEntity(): Entity {...}
    
        companion object {
            fun from(entity: Entity): Dto {...}
        }
    }
    
[/code]

* * *

依存関係を正常に保つ別の手段としては、 `Entity` <\--> `Dto`
の変換機能を別のクラス(下図の`Converter`)に委譲する、というのもあります。こうすれば、 `Entity` と `Dto`
の直接の依存関係を断てます:

[![画像の説明をここに入力](https://i.stack.imgur.com/ZaJqx.png)](https://i.stack.imgur.com/ZaJqx.png)

[code]

    class Converter {
        fun toEntity(dto: Dto): Entity {...}
        fun toDto(entity: Entity): Dto {...}
    }
    
[/code]

変換機能を自動生成する(例: [MapStruct](https://github.com/mapstruct/mapstruct-
examples/tree/main/mapstruct-kotlin))ならば、自然とこの形になるでしょう。


CC BY-SA 4.0
2022-08-30T15:49:07.037
90844
2022-08-30T15:55:14.973
2022-08-30T15:55:14.973
2808
2808
90835
answer