$30 off During Our Annual Pro Sale. View Details »

NestJSのDIコンテナで作るクリーンなレイヤー境界

 NestJSのDIコンテナで作るクリーンなレイヤー境界

NestJS Meetup Online #2 にて発表した内容です。

https://nest-jp.connpass.com/event/244015/

kimutyam

May 20, 2022
Tweet

More Decks by kimutyam

Other Decks in Technology

Transcript

  1. גࣜձࣾΧέϋγɹ໦ଜজ޺
    /FTU+4ͷ%*ίϯςφͰ࡞ΔΫϦʔϯͳϨ
    ΠϠʔڥք
    /FTU+4NFFUVQ0OMJOFɹ

    View Slide

  2. ࢹௌऀ૚ɾಡऀ૚ͷ૝ఆ
    w ҎԼͷ͍ͣΕ͔ʹ֘౰
    w /FTU+4Ͱ8FCΞϓϦέʔγϣϯΛ૊Μͩ͜ͱ͕͋Δ
    w /FTU+4ͷ1SPWJEFS.PEVMFΛ৮ͬͨ͜ͱ͕͋Δ
    w ΦϒδΣΫτࢦ޲Ͱͷઃܭɾ։ൃܦݧ͕͋Δ

    View Slide

  3. ࣗݾ঺հ
    w גࣜձࣾΧέϋγ d

    w ҩྍ඼ൃ஫ɾ؅ཧ࠷దԽྖҬͷ৽نࣄۀͷ্ཱͪ͛Λ୲౰த
    w ιϑτ΢ΣΞΤϯδχΞσʔλΤϯδχΞΞʔΩςΫτ
    w Χέϋγͱ5ZQF4DSJQU
    w גࣜձࣾΧέϋγY5ZQF4DSJQU"EWFOU$BMFOEBS
    w ͳͥόοΫΤϯυ5ZQF4DSJQU͔ʁٕज़બఆഎܠͱ࣮ફྫΛ঺հ͠·͢
    ໦ଜজ޺ ͖ΉΒ͖͋ͻΖ

    ˞ܦྺͷৄࡉ͸/FTU+4.FFUVQ0OMJOFͷΠϕϯτϖʔδʹهࡌ͍ͯ͠·͢

    View Slide

  4. 5XJUUFSIUUQTUXJUUFSDPNLJNVUZBN
    .FEJVNIUUQTLJNVUZBNNFEJVNDPN
    4QFBLFS%FDLIUUQTTQFBLFSEFDLDPNLJNVUZBN
    (JUIVCIUUQTHJUIVCDPNLJNVUZBN
    'PMMPX.F

    View Slide

  5. ΞδΣϯμ
    ΫϦʔϯͳϨΠϠʔڥքΛ૊ΉͨΊͷߟ͑ํ
    /FTU+4ͷ%*ίϯςφͷ࢓૊Έ
    ϨΠϠʔڥքΛߏ੒͢Δ
    औΓѻΘͳ͍͜ͱ
    w ΫϦʔϯΞʔΩςΫνϟͷਂ͍આ໌
    w υϝΠϯϞσϦϯάͷ࢓ํ
    ηΫγϣϯ

    View Slide

  6. ΫϦʔϯͳϨΠϠʔڥքΛ૊ΉͨΊͷߟ
    ͑ํ
    ηΫγϣϯ

    View Slide

  7. w ΫϦʔϯΞʔΩςΫνϟͰ༗໊ͳਤͰ͢ɻ
    w ͜ΕΒͷಉ৺ԁͷ಺ଆʹ͍͘΄Ͳιϑτ΢ΣΞͱ
    ্ͯ͠ҐϞδϡʔϧʹͳΔ͜ͱ͕ࣔ͞Ε͍ͯ·͢ɻ
    w υϝΠϯۦಈઃܭͷจ຺ͩͱɺ&OUJUJFT͸ศ্ٓυ
    ϝΠϯϞσϧͱදݱ͢Δ৔߹͕͋Γ·͢ɻ
    w ಉ৺ԁͷ࿮ΛϨΠϠʔڥքͱݺͼ·͢ɻ
    w ಉ৺ԁͷ࿮Λԣஅ͢Δʮˠʯ͸ґଘؔ܎Ͱ͢ɻ
    ΫϦʔϯͳϨΠϠʔڥքΛ૊ΉͨΊͷߟ͑ํ
    ΫϦʔϯΞʔΩςΫνϟ
    IUUQTCMPHDMFBODPEFSDPNVODMFCPCUIFDMFBOBSDIJUFDUVSFIUNM

    View Slide

  8. ΫϦʔϯͳϨΠϠʔڥքΛ૊ΉͨΊͷߟ͑ํ
    ґଘؔ܎ٯసͷݪଇ %FQFOEFODZ*OWFSTJPO1SJODJQMF

    l্ҐϞδϡʔϧ͸͍͔ͳΔ΋ͷ΋ԼҐϞδϡʔϧ
    ͔Β࣋ͪࠐΜͰ͸ͳΒͳ͍ɻ૒ํͱ΋ந৅ʢྫͱ͠
    ͯΠϯλʔϑΣʔεʣʹґଘ͢Δ΂͖Ͱ͋Δɻz˞
    lந৅͸ৄࡉʹґଘͯ͠͸ͳΒͳ͍ɻৄࡉʢ۩৅త
    ͳ࣮૷಺༰ʣ͕ந৅ʹґଘ͢Δ΂͖Ͱ͋Δɻz˞
    ґଘؔ܎ٯసύλʔϯͰ͸ɺΠϯλʔϑΣʔεΛ஥հ
    ͤ͞Δ͜ͱͰ্ҐϞδϡʔϧͷґଘΛճආ͍ͯ͠·
    ͢ɻ
    ,MPES౤ߘऀࣗ਎ʹΑΔஶ࡞෺ $$දࣔܧঝ IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJEʹΑΔ
    ,MPES౤ߘऀࣗ਎ʹΑΔஶ࡞෺ $$දࣔܧঝ IUUQTDPNNPOTXJLJNFEJBPSHXJOEFYQIQ DVSJEʹΑΔ
    ӈ্ը૾
    ӈԼը૾
    ˞ IUUQTKBXJLJQFEJBPSHXJLJґଘੑٯసͷݪଇ
    ैདྷͷϨΠϠʔύλʔϯ
    ґଘؔ܎ٯసύλʔϯ

    View Slide

  9. w ґଘؔ܎ٯసͷݪଇʹैͬͨઃܭΛ͢Δͱɺ࠷ऴ
    తʹΠϯλʔϑΣʔεͷ࣮૷Λඥ෇͚Δඞཁ͕ग़ͯ
    ͖·͢ɻͦ͜Ͱɺґଘੑͷ஫ೖ %*
    Λߦ͍·͢ɻ
    w ্ͷίʔυ͸ɺίϯετϥΫλͰґଘੑΛ஫ೖ͢
    ΔྫͰ͢ ίϯετϥΫλ%*
    ɻ
    w %*ͱ͸ɺґଘؔ܎ΛΫϥεؔ਺ͷ֎͔Β౉͢͜ͱ
    Ͱ͢ɻ
    w ͳ͓ɺԼͷίʔυ͸ɺ.FDIBOJTN಺෦Ͱ1PMJDZͷ
    ۩৅Ϋϥε͕ґଘͯ͠ɺґଘੑͷz஫ೖzʹ͸ͳͬͯ
    ͍·ͤΜɻ
    ΫϦʔϯͳϨΠϠʔڥքΛ૊ΉͨΊͷߟ͑ํ
    ґଘੑͷ஫ೖ %FQFOEFODZ*OKFDUJPO

    export class MechanismService
    {

    constructor(private policyService: IPolicyService)
    {

    }

    // ུ
    }

    export class MechanismService
    {

    private policyService: IPolicyService = new PolicyService(
    )

    // ུ


    }

    View Slide

  10. w %*Λ࢖ͬͨΫϥεઃܭΛਐΊΔͱɺґଘؔ܎Λղ
    ܾ͢ΔӈͷΑ͏ͳίʔυ͕ੜ·Ε·͢ɻ
    w Ϋϥε͕গͳ͍͏ͪ͸໰୊ʹͳΓ·ͤΜ͕ɺ૿͑
    ͖ͯͨ࣌͸ෆཁͳෳࡶੑΛੜΉ৔߹͕͋Γ·͢ɻ
    w %*ίϯςφ͸ӈͷίʔυΛॻ͔ͣʹґଘؔ܎ͷϏ
    δωεϩδοΫͷ֎ଆͰ؅ཧ͢Δ͜ͱ͕Ͱ͖·
    ͢ɻ
    w ͦͯ͠ɺ%*ίϯςφ͸/FTU+4ͷओཁͳػೳͷͭ
    Ͱ͢ɻ
    ΫϦʔϯͳϨΠϠʔڥքΛ૊ΉͨΊͷߟ͑ํ
    %*ίϯςφ͸ԿΛղܾ͢Δ͔ʁ
    new UtilityService
    (

    new MechanismService
    (

    new PolicyService(
    )

    )

    )

    View Slide

  11. /FTU+4ͷ%*ίϯςφͷ࢓૊Έ
    ηΫγϣϯ

    View Slide

  12. w ·ͣ͸؆୯ͳྫ͔Βɻ
    w $BUT4FSWJDFͷґଘؔ܎͸ɺ!.PEVMFΛӈͷΑ͏
    ʹఆٛ͢Ε͹%*Ͱ͖·͢ɻ
    w ͜ͷྫ͸ɺ$BUT4FSWJDFzΫϥεzΛ$BUT$POUSPMMFS
    ͰίϯετϥΫλ%*͍ͯ͠·͢ɻ
    /FTU+4ͷ%*ίϯςφͷ࢓૊Έ
    1SPWJEFS
    @Controlle
    r

    class CatsService {
    }

    @Controller("cats")
    class CatsController
    {

    constructor(private catsService: CatsService)
    {

    }

    // ུ


    }

    @Module(
    {

    controllers: [CatsController]
    ,

    providers: [CatsService]
    ,

    }
    )

    export class AppModule {}

    View Slide

  13. w ΠϯλʔϑΣʔεͷ৔߹͸ɺ޻෉͕ඞཁͰ͢ɻ
    w +BWB4DSJQU͸ΠϯλʔϑΣʔεΛαϙʔτͯ͠
    ͍ͳ͍ͨΊɺ5ZQF4DSJQUΛ+BWB4DSJQUʹίϯ
    ύΠϧ͢ΔͱɺΠϯλʔϑΣʔεͷఆٛ͸ফࣦ
    ͠·͢ɻ
    w τʔΫϯ ྫͰ͸$"54@4&37*$&@50,&/
    Ͱ
    /FTU+4ͷ*OKFDUFSͰࣝผՄೳͳঢ়ଶʹ͢Δඞཁ͕
    ͋Γ·͢ɻ
    /FTU+4ͷ%*ίϯςφͷ࢓૊Έ
    1SPWJEFS
    interface ICatsService {
    }

    class CatsService implements ICatsService {
    }

    const CATS_SERVICE_TOKEN = "CATS_SERVICE_TOKEN"
    ;

    class CatsController
    {

    constructor
    (

    @Inject(CATS_SERVICE_TOKEN
    )

    private catsService: ICatsServic
    e

    )
    {

    }

    // ུ
    }

    export const CatServiceProvider: Provider =
    {

    provide: CAT_SERVICE_TOKEN
    ,

    useClass: CatsService
    ,

    }
    ;

    @Module(
    {

    controllers: [CatsController]
    ,

    providers: [CatServiceProvider]
    ,

    }
    )

    export class AppModule {
    }

    View Slide

  14. /FTU+4ͷ%*ίϯςφͷ࢓૊Έ
    !.PEVMFͱ͸Կ͔ʁ
    .PEVMF#
    .PEVMF"
    FYQPSUT
    JNQPSUT
    JNQPSUT
    1SPWJEFS
    1SPWJEFS
    $POUSPMMFS
    QSPWJEFST
    /FTU+4ͷΠϯδΣΫλʹΑͬͯΠϯελϯ
    εԽ͞Εɺগͳ͘ͱ΋Ϟδϡʔϧ಺Ͱڞ༗
    ͞ΕΔ
    DPOUSPMMFST
    .PEVMF಺ͷΠϯελϯεԽ͢Δඞཁ͕͋Δ
    $POUSPMMFSҰཡ
    JNQPSUT
    ͜ͷϞδϡʔϧʹFYQPSU͢ΔผͷϞδϡʔ
    ϧͷҰཡ
    FYQPSUT
    ผͷϞδϡʔϧͰ͜ͷϞδϡʔϧΛJNQPSU
    ͢ΔͨΊͷɺެ։͢ΔϓϩόΠμٴͼτʔ
    ΫϯͷϦετ

    View Slide

  15. ϨΠϠʔڥքΛߏ੒͢Δ
    ηΫγϣϯ

    View Slide

  16. ϨΠϠʔڥքΛߏ੒͢Δ
    IUUQTCMPHDMFBODPEFSDPNVODMFCPCUIFDMFBOBSDIJUFDUVSFIUNM
    ߏ੒͢ΔΫϥεਤ

    View Slide

  17. ϨΠϠʔڥքΛߏ੒͢Δ
    ߏ੒͢ΔΫϥεਤ
    w ֤ϨΠϠʔຖ EPNBJOVTF$BTF
    QSJNBSZ"EBQUPSTFDPOEBSZ"EBQUPS
    ʹͦΕͧ
    Ε.PEVMFΛ࡞੒͠·͢
    w ͦΕΒΛ࠷ऴతʹ.PEVMFΛଋͶ·͢ɻ
    w <ิ଍>QSJNBSZͱTFDPOEBSZͱ͸ʁ
    w ΫϦʔϯΞʔΩςΫνϟͷલਐͱͳͬͨ
    1PSUT"EBQUPSTΞʔΩςΫνϟͷ༻ޠͰ
    ͢ɻ
    w QSJNBSZ͸ʮۦಈ͢ΔʯΞμϓλ
    w TFDPOEBSZ͸ʮۦಈ͞ΕΔʯΞμϓλ

    View Slide

  18. w 3FQPTJUPSZ΍3FRVFTUFS͸*'ͷΈͰ͢ɻ
    w ۩ମతͳ࣮૷Λ͢ΔͱΞμϓλ૚ٴͼͦΕΑ
    Γ΋֎ͷԁʹґଘͯ͠͠·͏ͨΊͰ͢ɻ
    w Ұ൪্ҐϞδϡʔϧʹͳΔͨΊz஫ೖz͢Δґଘ͸
    ͳ͍ͨΊɺ.PEVMF͸͋Γ·ͤΜɻ
    w ͳ͓ɺτʔΫϯ͸Ϣʔεέʔε૚ͷ࣮૷Ͱ࢖͏ͨ
    Ίɺ͜͜ʹ഑ஔ͍ͯ͠·͢ɻ
    ϨΠϠʔڥքΛߏ੒͢Δ
    υϝΠϯ૚ EPNBJO

    export type Cat = Readonly<
    {

    id: CatId
    ;

    name: CatName
    ;

    age: CatAge
    ;

    }>
    ;

    export const CAT_REPOSITORY_TOKEN = 'CAT_REPOSITORY_TOKEN'
    ;

    export interface ICatRepository
    {

    store(cat: Cat): Promise
    ;

    }

    export const CAT_REQUESTER_TOKEN = 'CAT_REQUESTER_TOKEN'
    ;

    export interface ICatRequester
    {

    get(catId: CatId): Promise
    ;

    }

    View Slide

  19. w ʮೣΛड͚औΔʯͱ͍͏ϢʔεέʔεΛ૝ఆͨ͠
    ࣮૷Ͱ͢ɻ
    w 6TF$BTF͸*'Ͱɺͦͷ࣮૷Ϋϥε͸*OUFSBDUPS
    Ͱ͢ɻ
    w *OUFSBDUPSͰ͸υϝΠϯ૚Ͱఆٛͨ͠*'Λίϯε
    τϥΫλͷҾ਺ʹఆ͍ٛͯ͠·͢ɻ
    ϨΠϠʔڥքΛߏ੒͢Δ
    Ϣʔεέʔε૚ 6TF$BTF
    export interface UseCase
    {

    run(input: In): Promise
    ;

    }

    export type Input = Readonly<
    {

    catId: CatId
    ;

    }>
    ;

    export type Output = Omit
    ;

    export type ReceiveCatUseCase = UseCase
    ;

    export const RECEIVE_CAT_USECASE_TOKEN =
    'RECEIVE_CAT_USECASE_TOKEN'
    ;

    @Injectable(
    )

    export class ReceiveCatInteractor implements ReceiveCatUseCase
    {

    constructor
    (

    @Inject(CAT_REPOSITORY_TOKEN
    )

    private catRepository: ICatRepository
    ,

    @Inject(CAT_REQUESTER_TOKEN
    )

    private catRequester: ICatRequester
    ,

    ) {
    }

    async run({ catId }: Input): Promise
    {

    const cat = await this.catRequester.get(catId);


    // ུ
    }

    }

    View Slide

  20. ϨΠϠʔڥքΛߏ੒͢Δ
    Ϣʔεέʔε૚ 6TF$BTF

    w ηΧϯμϦʔΞμϓλͷΫϥε ྘
    Λ࣮૷ͱͯ͠
    ࠾༻͢Δ͜ͱʹ͢Δ৔߹͸ɺηΧϯμϦΞμϓλ
    ͷ.PEVMFΛJNQPSU͠·͢ɻ
    w ͜ΕΛ౿·͑ͯ࣍ͷϖʔδͰ͸.PEVMFΛ࡞੒͠
    ·͢ɻ

    View Slide

  21. w ηΧϯμϦʔΞμϓλͷ.PEVMF ޙड़
    ΛJNQPSU
    ͍ͯ͠·͢
    w ϢʔεέʔεΛଞͷ.PEVMFͰར༻Ͱ͖ΔΑ͏ʹ
    ϓϩόΠμΛFYQPSU͍ͯ͠·͢
    w ϓϥΠϚϦΞμϓλͷ.PEVMF ޙड़
    ͰJNQPSU
    ͠·͢ɻ
    w <ิ଍>6TF$BTF.PEVMF͸ΠϯλʔϑΣʔεΞμ
    ϓλʹґଘ͍ͯ͠·͕͢ɺϩδοΫ͕ґଘ͍ͯ͠
    ΔΘ͚Ͱ͸͋Γ·ͤΜɻ
    ϨΠϠʔڥքΛߏ੒͢Δ
    Ϣʔεέʔε૚ 6TF$BTF

    export const ReceiveCatUseCaseProvider: Provider =
    {

    provide: RECEIVE_CAT_USECASE_TOKEN
    ,

    useClass: ReceiveCatInteractor
    ,

    }
    ;

    @Module(
    {

    imports: [AdaptorMemoryStoreModule,
    AdaptorPetShopApiModule]
    ,

    providers: [ReceiveCatUseCaseProvider]
    ,

    exports: [ReceiveCatUseCaseProvider]
    ,

    }
    )

    export class UseCaseModule {
    }

    View Slide

  22. w υϝΠϯ૚ͷϦϙδτϦͷ*'Λ࣮૷͍ͯ͠·͢ɻ
    w ϦϙδτϦͷϓϩόΠμΛଞͷ.PEVMFͰ׆༻Ͱ
    ͖ΔΑ͏ʹFYQPSU͍ͯ͠·͢ɻ
    w Ϣʔεέʔεͷ.PEVMFͰJNQPSU͠·͢ɻ
    ϨΠϠʔڥքΛߏ੒͢Δ
    ΠϯλʔϑΣʔεΞμϓλ૚ 4FDPOEBSZ"EBQUPS

    @Injectable(
    )

    export class CatRepository implements ICatRepository
    {

    store(cat: Cat): Promise
    {

    // ུ
    }

    }

    export const CatRepositoryProvider: Provider =
    {

    provide: CAT_REPOSITORY_TOKEN
    ,

    useClass: CatRepository
    ,

    }
    ;

    @Module(
    {

    providers: [CatRepositoryProvider]
    ,

    exports: [CatRepositoryProvider]
    ,

    }
    )

    export class AdaptorMemoryStoreModule {
    }

    View Slide

  23. w $BU$POUSPMMFSͷ࣮૷Ͱ͢ɻ
    w 6TF$BTF͸*'ͱ1SFTFOUFSͷΫϥεΛίϯετ
    ϥΫλͰఆ͍ٛͯ͠·͢ɻ
    ϨΠϠʔڥքΛߏ੒͢Δ
    ΠϯλʔϑΣʔεΞμϓλ૚ 1SJNBSZ"EBQUPS

    @Injector(
    )

    export class CatPresenter {
    }

    @Controller('/cat'
    )

    export class CatController
    {

    constructor
    (

    @Inject(RECEIVE_CAT_USECASE_TOKEN
    )

    private receiveCatUseCase: ReceiveCatUseCase
    ,

    private catPresenter: CatPresenter
    ,

    ) {
    }

    @Put(':id'
    )

    async receive(@Param('id') id: string):
    Promise
    {

    // ུ
    }

    }

    View Slide

  24. ϨΠϠʔڥքΛߏ੒͢Δ
    ΠϯλʔϑΣʔεΞμϓλ૚ 1SJNBSZ"EBQUPS

    w $POUSPMMFS ੨
    ͷґଘؔ܎Λղܾ͢ΔͨΊʹɺ
    *OUFSBDUPSͷϓϩόΠμʔΛؚΉϢʔεέʔεͷ
    .PEVMF͕ඞཁʹͳΓ·͢ɻ
    w ·ͨɺ͜ͷྫͰ͸1SFTFOUFSͷґଘؔ܎΋ղܾ͢
    Δඞཁ͕͋Γ·͢ɻ
    w ͜ΕΛ౿·͑ͯ࣍ͷϖʔδͰ͸.PEVMFΛ࡞੒͠
    ·͢ɻ

    View Slide

  25. w Ϣʔεέʔεͷ.PEVMFΛJNQPSUͯ͠ɺ
    $POUSPMMFSͷίϯετϥΫλ%*͍ͯ͠·͢ɻ
    w DPOUSPMMFSTʹίϯτϩʔϥʔͷࢦఆΛ͍ͯ͠·
    ͢ɻ
    w 1SFTFOUFSΫϥεΛQSPWJEFSTʹࢦఆ͍͠·͢ɻ
    w <ิ଍>͜͜Ͱ͸Ϣʔεέʔεͷ*'ʹґଘ͍ͯ͠·
    ͕͢ɺϢʔεέʔεͷ*'Λ੾Βͣʹ۩৅Ϋϥεͷ
    ࢦఆͰ΋໰୊͋Γ·ͤΜɻ
    w *'ʹґଘ͍ͤͯ͞Δͷ͸$POUSPMMFSͷςελ
    ϏϦςΟΛ޲্ͤ͞ΔͨΊͰ͢ɻ
    ϨΠϠʔڥքΛߏ੒͢Δ
    ΠϯλʔϑΣʔεΞμϓλ૚ 1SJNBSZ"EBQUPS

    @Module(
    {

    imports: [UseCaseModule]
    ,

    controllers: [CatController]
    ,

    providers: [CatPresenter]
    ,

    }
    )

    export class AdaptorWebApiModule {
    }

    View Slide

  26. w ࠷ऴతʹ"QQ.PEVMFͰࠓ·Ͱ࡞੒ͨ͠.PEVMF
    ΛJNQPSU͠·͢
    w ηΧϯμϦʔΞμϓλ͸6TF$BTF.PEVMFͰ
    JNQPSU͞Ε͍ͯΔͨΊ͜͜Ͱ͸ෆཁͰ͢ɻ
    w "QQ.PEVMFΛ/FTU'BDUPSZDSFBUFʹ౉ͯ͠׬
    ੒Ͱ͢ɻ
    ϨΠϠʔڥքΛߏ੒͢Δ
    "QQ.PEVMF
    @Module(
    {

    imports: [UseCaseModule, AdaptorWebApiModule]
    ,

    }
    )

    export class AppModule {
    }

    export async function main()
    {

    const app = await NestFactory.create(AppModule)
    ;

    await app.listen(80, '0.0.0.0')
    ;

    }

    View Slide

  27. ࠷ޙʹ

    View Slide

  28. ࠷ޙʹ
    w ΫϦʔϯͳϨΠϠʔڥքΛ࡞ΔͨΊʹɺґଘؔ܎ٯసͷݪଇΛ׆༻͠ґଘؔ܎Λ஫ೖ͠·͢ɻ
    w %*ίϯςφΛ࢖͏ͱɺ࣮૷ͱઃఆΛ෼͚ͯґଘؔ܎ͷ഑ઢ͕Ͱ͖·͢ɻ
    w /FTU+4ͷ.PEVMFTΛ࢖͑͹ґଘؔ܎ͷ஫ೖͷ෼ׂ౷࣏͕ՄೳͰ͢ɻ
    w ࠓճ͸ϨΠϠʔผʹ഑ઢͷ෼ׂ౷࣏Λ͠·ͨ͠ɻ
    w αϯϓϧίʔυ͸ҎԼ
    w IUUQTHJUIVCDPNLJNVUZBNOFTUKTDMFBOBSDIJUFDUVSFUSFF
    ·ͱΊ

    View Slide

  29. ࠷ޙʹ
    w ૊Έํͷߟ͑ํ͸ಉ͡Ͱ͕͢ɺ͜͜Ͱઆ໌ͨ͠ͷ͸ύλʔϯͰ͢ɻ
    w ϓϩδΣΫτͷঢ়گ΍ϓϩμΫτͷಛ௃ʹΑͬͯͲ͏͍͏ߏ੒ʹ͢Δ͔͸ݕ౼͠·͠ΐ͏ɻ
    w ͨͩ͠ɺߏ੒Λ૊Ή্Ͱͷߟ͑ํ͸ಉ͡Ͱ͢ɻ
    w lΞʔΩςΫνϟͷϧʔϧ͸ͲΕ΋ಉ͡Ͱ͋Δʂz˞
    ஫ҙॻ͖
    ˞3PCFSU$.BSUJO
    ʰ$MFBO"SDIJUFDUVSFୡਓʹֶͿιϑτ΢ΣΞͷߏ଄ͱઃܭʱʮংจʯΑΓ

    View Slide

  30. ࠷ޙʹ
    8FBSF)JSJOH
    w ΤϯδχΞʹؔͯ͠ଟ͘ͷٻਓ͕͍͟͝·͢ɻ˞
    w όοΫΤϯυʹؔͯ͠΋5ZQF4DSJQUΛओཁݴޠͱ
    ͨ͠ืू࿮΋͋Γ·͢ɻ˞
    w 8FCͷϑϩϯτΤϯυ͸5ZQF4DSJQUΛར༻͍ͯ͠
    ·͢ɻ˞
    IUUQTIFSQDBSFFSTWLBLFIBTIJ
    ˞ొஃ࣌఺Ͱͷٻਓ৘ใͰ͢ɻ

    View Slide