Open3

DDD依存

katayama8000katayama8000

抽象 (interface) に依存

interface IUserRepository {
  find(): void;
}

class UserRepository implements IUserRepository {
  // 永続化に関する処理
  // DBに書き込むなど
  find(): void {
    console.log("find");
    // connect DB and do something
  }
}

class UserService {
  private userRepository: IUserRepository;

  constructor(userRepository: IUserRepository) {
    this.userRepository = userRepository;
  }

  public find(): void {
    this.userRepository.find();
  }
}

const userRepository: IUserRepository = new UserRepository();
const userService = new UserService(userRepository);
userService.find();
katayama8000katayama8000

実態に依存

class UserRepository  {
  // 永続化に関する処理
  // DBに書き込むなど
  find(): void {
    console.log("find");
    // connect DB and do something
  }
}

class UserService {
  private userRepository: UserRepository

  constructor(userRepository: UserRepository) {
    this.userRepository = userRepository;
  }

  public find(): void {
    this.userRepository.find();
  }
}

const userRepository = new UserRepository();
const userService = new UserService(userRepository);
userService.find();
katayama8000katayama8000

抽象に依存すると何がうれしいのか

データベースの変更

例えば、Firebase を使用しているプロジェクトがあり、NoSQL ではなく、RDBを使いたい場合があるとする。
実態に依存している場合、UserRepository を全て書き換える必要があるが、抽象に依存している場合、依存している interface を満たしていれば、差し替えるだけで、事足りる

class User {
  private name: string;
  private age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

interface IUserRepository {
  find(): User;
  store(): void;
}

class UserRepositoryWithMySQL implements IUserRepository {
  find(): User {
    // connect MySQL and find user
    return new User("test", 20);
  }
  store(): void {
    console.log("store");
  }
}

class UserRepositoryWithFireBase implements IUserRepository {
  find(): User {
    // connect FireBase and find user
    return new User("test", 20);
  }
  store(): void {
    console.log("store");
  }
}

class UserService {
  private userRepository: IUserRepository;

  constructor(userRepository: IUserRepository) {
    this.userRepository = userRepository;
  }

  public find(): User {
    return this.userRepository.find();
  }

  public store(): void {
    this.userRepository.store();
  }
}

const userRepositoryWithMySQL: IUserRepository = new UserRepositoryWithMySQL();
const userRepositoryWithFireBase: IUserRepository =
  new UserRepositoryWithFireBase();
const userService1 = new UserService(userRepositoryWithMySQL);
const userService2 = new UserService(userRepositoryWithFireBase);
userService1.find();
userService1.store();
userService2.find();
userService2.store();

極端にいうと、DBはなんであろうとも、ごっそり変えることができるのである