계약 프로그래밍을 의식하면 대상을 방향으로

7218 단어 시가idea

개시하다


계약 프로그래밍과 대상을 향한 방향을 정확하게 이해할 수 있을지 의심스러우니 널리 양해해 주십시오

계약 절차 설계?


https://ja.wikipedia.org/wiki/계약 절차 설계
선행 조건
서브루틴이 시작될 때, 이 측이 보증해야 할 성질을 호칭한다.
사후 조건
서브루틴이 끝날 때 보증해야 하는 성질.
불변 조건(invariant)
클래스 등 대상이 외부에 공개된 모든 조작의 시작과 끝은 각 대상의 공통성을 보증해야 한다.
이런 견해가 있다.
그 중에서 사전 조건과 사후 조건은 정태적인 고정된 언어 형식으로 표현할 수 있을 것 같다.

예제


규격.


메일 주소와 비밀번호로 서명할 수 있는 시스템.
DB에 해싱된 암호를 저장합니다.

일반적 실현


언어는 kotlin입니다.
class UserRepository (
  private userDao: UserDao
) {
  fun signUp(email: String, password: String): User =
    userDao.create(email, password)
}

문제점


매개 변수email가 정확한지 산열password인지 모르기 때문에 다른 실현자가 잘못 실현할 수 있습니다.

계약 절차 설계를 의식적으로 실시하다


class Email(val value: String) {
  init {
    require(EmailValidator.getInstance().isValid(value))
  }
}

class HashedPassword(_value: String) {
  val value = BCryptPasswordEncoder().encode(_value)
}

class UserRepository (
  private userDao: UserDao
) {
  fun signUp(email: Email, password: HashedPassword): User =
    userDao.create(email.value, password.value)
}
이렇게 하면 "Repository에 보고하기 전에 반드시 Email의 검증과 비밀번호의 산열을 확인해야 한다"(사전 조건)를 나타낼 수 있다.
사후 조건은 귀환치로 표시할 수 있다.예를 들어 아까의 예에서 HashedPassword의 구조기가 한 처리를 공장으로 옮길 수 있다.
class HashedPassword private constructor (val value: String) {
  companion object {
    fun of(str: String): HashedPassword = HashedPassword(BCryptPasswordEncoder().encode(str))
  }
}
정상적으로 구현되는 경우
object PasswordUtil {
  fun hashed(str: String): String = BCryptPasswordEncoder().encode(str)
}
어때요?
그런데 아까 그 방법을 생각하면
메일 주소와 비밀번호로 서명할 수 있는 시스템.
DB에 해싱된 암호를 저장합니다.
메일 주소, 흩어진 비밀번호도 코드 형식으로 나온다.
응, 이렇게 스타일을 정형화하는 게 대상을 향한 거야?ValueObject?뭐라고 생각하십니까?
잘못했는지 모르겠지만 개인적으로 잘 어울린다고 생각해요.

좋은 웹페이지 즐겨찾기