引き受けたコンテキスト型の内部で 関数を実行していることになる。 = 複数の型に対し拡張できるイメージ class UserUseCase { context(Logger, Storage<User>) fun userInfo(name: String): Storage<User>.Info { log("Retrieving User info about $name") return info(name) } } Logger Storage<User> fun info(name: String): Info fun log(message: String): Unit 関数定義の例 UserUseCase fun userInfo(name: String): Storage.Info
Controller fun getItems(req: Request): Response { val result = usecase.getItems(req.user, req.itemId) return ItemsResponse.from(result) } // Usecase fun getItems(user: User): Result { val item = repository.getItem(itemId) val recommended = getRecommendedItems(user, itemId) return Result(item, recommended) } // API Client fun getRecommendedItems(user: User, itemId: String): List<Item> レイヤーを跨いでuserのバケツリレーをしている ② セッションやトランザクションの引き回し
Javaにはあるチェック例外の機構がKotlinでは意図的に省かれている。 一方で、エラー型を定義して返却するのは良いプラクティスとされている ゆえに極力エラー時の型はシグネチャから分かるようにしておきたい。 class PositiveInt { private int value; public PositiveInt(int value) throws InvalidNumberException { if (value < 0) { throw new InvalidNumberException("Number cannot be less than 0"); } this.value = value; } } チェック例外を使うJavaコード例