Skip to content

Instantly share code, notes, and snippets.

View rinotc's full-sized avatar

Chiba Toshinori rinotc

View GitHub Profile
@rinotc
rinotc / precondition-adt-sample_first_CreateUserInteractor.scala
Created May 20, 2022 12:41
ドメインサービスでバリデーション入れた場合のサンプル
package first
import first.usecase.{CreateUserInput, CreateUserOutput, CreateUserUseCase}
final class CreateUserInteractor(userService: UserService, userRepository: UserRepository) extends CreateUserUseCase {
override def handle(input: CreateUserInput): CreateUserOutput = {
val newUser = User.create(input.name)
userService.exists(newUser) match { // このバリデーションが必ず必要だが、知らないとできない。
class Person private (val firstName: String, val lastName: String, val age: Int)
object Person {
class Builder {
var firstName: String = ""
var lastName: String = ""
var age: Int = 0
private var hasFirstName: Boolean = false
private var hasLastName: Boolean = false
package sample2
import user.{UserId, UserName, UserNameDuplicateError}
/**
* ユーザー
*
* @note デフォルトコンストラクタは `private` にして生成処理を絞っている。
* ADTを利用した状態遷移はインスタンスの生成方法の制御が重要である。
* 型パラメータを自由につけてインスタンスを生成できては、制約の効果がないためだ。
package sample2
import usecase.create.CreateUserOutput.UserNameConflict
import usecase.create.{CreateUserInput, CreateUserOutput, CreateUserUseCase}
class CreateUserInteractor(
userNameConflictValidator: UserNameConflictValidator,
userRepository: UserRepository
) extends CreateUserUseCase {
@rinotc
rinotc / english-name.ts
Created May 21, 2022 01:30
typescriptで値オブジェクト書いてみたサンプル
import {PreferNominal} from "../../prefer-nominal";
import * as E from "fp-ts/Either";
export class EnglishName {
// noinspection JSUnusedGlobalSymbols
readonly _englishNameBrand: PreferNominal;
constructor(readonly value: string) {
if (!EnglishName.isValid(value)) {
throw new TypeError(this.requirementErrorMessage);
@rinotc
rinotc / rust-self-memo.rs
Last active December 24, 2022 02:34
Rustの self, &self, &mut self に関するメモ
fn main() {
let mut rect = Rectangle {
width: 10,
height: 15,
};
println!("rectangle area is: {}", rect.area());
// let mut で宣言されたものでないと呼び出せない。
rect.set_width(20);
// rect の内部状態が代わり、rect.widthが20になっているので、結果は300になる
println!("rectangle area is: {}", rect.area());
@rinotc
rinotc / DomainServiceCommonSample.scala
Last active March 12, 2023 14:46
よくあるドメインサービスの実装
trait UserEmailUniqueChecker extends DomainService {
/**
* 引数のメールアドレスがユニークであるかどうかを調べる
*/
def check(email: EmailAddress): Boolean
}
final class User private (
val id: UserId,
class ChangeEmailUseCase @Inject() (
userEmailUniqueChecker: UserEmailUniqueChecker,
userRepository: UserRepository
) {
import ChangeEmailOutput._
override def handle(input: ChangeEmailInput): ChangeEmailOutput = {
val result = for {
user <- userRepository.findById(input.userId).toRight(NotFoundUser(input.userId))