Upgrade to Pro — share decks privately, control downloads, hide ads and more …

why-typescript-with-clean-architecture.pdf

Avatar for Yujin Jeong Yujin Jeong
November 20, 2017
360

 why-typescript-with-clean-architecture.pdf

Avatar for Yujin Jeong

Yujin Jeong

November 20, 2017
Tweet

Transcript

  1. class Human { constructor(name, age) { this.name = name; this.age

    = age; } } class Profile extends React.Component { render() { const yujin = new Human('yujin', 24); return ( <div> <h1>{ yujin.name }</h1> <h2>{ `${yujin.age}ࣁ` }</h2> <h3>{ yujin.githubUrl }</h3> </div> ) } }
  2. class Human { constructor(name, age) { this.name = name; this.age

    = age; } } class Profile extends React.Component { render() { const yujin = new Human('yujin', 24); return ( <div> <h1>{ yujin.name }</h1> <h2>{ `${yujin.age}ࣁ` }</h2> <h3>{ yujin.githubUrl }</h3> </div> ) } } ী੉ࢸ݃
  3. FY ഌఖӝળਵ۽ݽٚ஠٘ࢎ੄नਊ஠٘ܳ࠺Ү೧઱੗ بݫੋ੹ޙо ূ૑פয "஠٘ࢎ஠٘ҳઑ ഌఖ҅࢑۽૒ #஠٘ࢎ஠٘ҳઑ оݚ੼੿ࠁ ഌఖҳઑ ഌఖ҅࢑੉оמೠ

    नਊ஠٘ݽ؛ ஠ؘ٘੉ఠా೤ ഌఖ੿ࠁழޭפா੉࣌۽૒ ࣗ࠺ಁఢ੿੄ ஠٘ ഌఖীҙೠبݫੋ૑ध j ؘ੉ఠా೤ҙܻ಴അਸਤೠ૑ध j
  4. &OUJUZ 6TF$BTF $POUSPMMFS 6* بݫੋ৔৉ بݫੋ੹ޙо৬೤੄ೠ઺ब৔৉ ѐߊ ӝദ ؘ੉ఠݽفৈӝࢲ୹ߊೠ׮ بݫੋ৔৉ী؀ೠ੉೧о֫ই૗ীٮۄ૑ࣘ੸ਵ۽ߊ੹

    ѐߊ঱য ࣽࣻۄ੉࠳۞ܻ৻੄ઓࢿ੉হ਺ ߸ച੄಩੉௼૑ঋ׮ ੉Ҕী௾߸ചо੓׮חѪ਷بݫੋਸੜޅ੉೧೮׮חѪ೐۽ં౟িযঠೠ׮
  5. &OUJUZ  بݫੋ੄೨बҳࢿਃࣗ  JE৬э਷Ҋਬࢿ੉ࠁ੢غחੋ੗۽&OUJUZ৬7BMVF0CKFDU۽ҳ࠙  ٍীࢲࢎ۹۽ਫ਼Ӭ׮ܖѷणפ׮ class User implements

    Entity { id: number; name: string; type: User.Type; constructor( id: number, name: string, type: User.Type ) { this.id = id; this.name = name; this.type = type; } }
  6. Repository - Entity를 제공하기 위한 Interface - 실제 구현은 DataSource에

    의존성을 가지는 Data Layer에서 이루어짐 interface UserRepositoryType extends RepositoryType { search(query: string): Observable<List<User>> }
  7. class SearchUsers extends UseCase<List<User>> { private repository: UserRepositoryType; query: string;

    constructor(repository: UserRepositoryType) { super(); this.repository = repository; } protected build(): Observable<List<User>> { return this.repository.search(this.query); } protected validate(): boolean { return !!this.query; } } UseCase - 도메인 영역의 End-Point - 실제로 서비스를 이용하는 사용자가 하는 행동을 정의 - repository의 interface 기능을 조합하여 원하는 결과값을 하나로 돌려준다
  8. %PNBJO-BZFS 6* 6TF$BTF 4FBSDI6TFST 3FQPTJUPSZ 6TFS3FQPTJUPSZ Ѩ࢝য -JTU6TFS *OQVU.PEFM -JTU&OUJUZ

    ൒ܴ੿ܻ tѨ࢝যܳੑ۱ೞݶ೧׼ೞחࢎਊ੗ݾ۾ਸࠁৈળ׮u
  9. %BUB-BZFS 6* 6TF$BTF 4FBSDI6TFST 3FQPTJUPSZ 6TFS3FQPTJUPSZ Ѩ࢝য -JTU6TFS *OQVU.PEFM -JTU&OUJUZ

    ൒ܴ੿ܻ tѨ࢝যܳੑ۱ೞݶ೧׼ೞחࢎਊ੗ݾ۾ਸࠁৈળ׮u
  10. 3FQPTJUPSZ  بݫੋ৔৉੄3FQPTJUPSZӝמਸҳഅ  ೙ਃೠ%BUB4PVSDFо઱ੑغযҳഅػ׮ interface UserRepositoryType extends RepositoryType {

    search(query: string): Observable<List<User>> } class UserRepository implements UserRepositoryType { private githubApi: GithubApiProvider; constructor(githubApi: GithubApiProvider) { this.githubApi = githubApi; } search(query: string): Observable<List<User>> { return this.githubApi.searchUser(query); } }
  11. "1*4FSWFS 6* 6TF$BTF 4FBSDI6TFST 3FQPTJUPSZ 6TFS3FQPTJUPSZ Ѩ࢝য -JTU6TFS *OQVU.PEFM -JTU&OUJUZ

    ൒ܴ੿ܻ tѨ࢝যܳੑ۱ೞݶ೧׼ೞחࢎਊ੗ݾ۾ਸࠁৈળ׮u
  12. 6*-BZFSী6TF$BTFܳઁҕೞӝਤ೧ݽٚJOTUBODFܳ઱ੑ೧સפ׮ interface ApiProviderDependencies { github: GithubApiProvider; } interface RepositoryDependencies {

    user: UserRepository; } interface UseCaseDependencies { searchUsers: SearchUsers; } class Context { private githubAxiosInstance: AxiosInstance; private apiProviders: ApiProviderDependencies; private repositories: RepositoryDependencies; useCases: UseCaseDependencies; constructor(githubAxiosInstance: AxiosInstance) { this.githubAxiosInstance = githubAxiosInstance; this.apiProviders = { github: new GithubApiProvider(githubAxiosInstance) }; this.repositories = { user: new UserRepository(this.apiProviders.github) }; this.useCases = { searchUsers: new SearchUsers(this.repositories.user) } } } const axiosInstance = Axios.create({ baseURL: Config.hosts.github, timeout: Config.timeout, headers: { 'Accept': 'application/json' } }); export const Application = new Context(axiosInstance);
  13. private renderUsers = (users: List<User>) => <ul> { users.map((user, i)

    => <li key={ `users-${i}` }> { user.name } </li> ) } </ul>; apply(Application.useCases.searchUsers, it => it.query = query) .runOnAnimateFrame() .subscribe( users => this.setState({ users, fetchState: FetchState.FETCHED }), error => this.setState({ fetchState: FetchState.ERROR }) ) .unsubscribeBy(this.subscriptionBag)
  14. t׳ۄ૓௏ܻ٘࠭u interface Event { id: string; name: string; } class

    CardCompanyEvent implements Event { id: string; name: string; } class StockFirmEvent implements Event { id: string; name: string; }
  15. interface Event { id: string; name: string; } class CardCompanyEvent

    implements Event { id: string; name: string; } class StockFirmEvent implements Event { id: string; name: string; } ܻ࠭ب઺ r&OUJUZী೧ࢳ੉ੌযդѪэ਷ؘ s t$BSE$PNQBOZ&WFOUJE4UPDL'JSN&WFOUJE੉ݶل੉э਷੉߮౟ীਃ u t׳ۄ૓௏ܻ٘࠭u