Pro Yearly is on sale from $80 to $50! »

iOS anti pattern thinking ANDROID

0b035ebcffb3af51d4b759733619beb0?s=47 yutaabe200
September 12, 2018

iOS anti pattern thinking ANDROID

アプリ開発と言うとほとんどがAndroid・iOS両OS開発するシーンがほとんどかと思われます。
その中でiOSでは容易に実装できるけどAndroidではキツイ!と言う実装やその逆のパターンも数多くあります。
本セッションではAndroid実装を考慮するとiOSでやってはいけないアンチパターンを両0S開発の経験を基にお話しします。

https://ore-con.firebaseapp.com/

0b035ebcffb3af51d4b759733619beb0?s=128

yutaabe200

September 12, 2018
Tweet

Transcript

  1. " / % 3 0 * % Λ ߟ ͑

    ͨ * 0 4 Ξ ϯ ν ύ λ ʔϯ            0 3 & $ 0 /       ʙ       5 3 " $ ,  #  : 6 5"  " # &
  2. 2 ࣗݾ঺հ ɾѨ෦༏ଠ!ZVUBBCF ɾגࣜձࣾΫʔωϧϫʔΫ!৽ׁ ɾJ04%$Ͱ΋ొஃͨ͠Α ɾJ04ྺ͸΋͏͙͢೥ ɾ"OESPJE΋࠷ۙ΍ͬͯΔΑ

  3. J04"OESPJE։ൃʹ͍ͭͯ Ξϯέʔτ

  4. 4 J04"OESPJE։ൃʹ͍ͭͯΞϯέʔτ ɾJ040OMZ%FWFMPQFS ɾ"OESPJE0OMZ%FWFMPQFS ɾJ04"OESPJE%FWFMPQFS

  5. 5 J04"OESPJE։ൃʹ͍ͭͯΞϯέʔτ ɾJ040OMZ%FWFMPQFS ɾ"OESPJE0OMZ%FWFMPQFS ɾJ04"OESPJE%FWFMPQFS

  6. 6 J04"OESPJE։ൃʹ͍ͭͯΞϯέʔτ ɾJ040OMZ%FWFMPQFS ɾ"OESPJE0OMZ%FWFMPQFS ɾJ04"OESPJE%FWFMPQFS

  7. None
  8. ͔ͤͬ͘ͳΒͲͬͪ΋࡞Εͨํ͕͍͍ΑͶʂʂ

  9. 9 5BSHFU ɾ͜Ε͔ΒJ04"OESPJEಉ࣌ωΠςΟϒ։ൃΛਓͰߦΘͳ͍ͱͳঢ়گͷํ ɾ"OESPJEΤϯδχΞʹ΍͍͞͠J04ΤϯδχΞʹͳΓ͍ͨํ

  10. 10 "HFOEB ɾࣗݾ঺հˡࠓऴΘͬͨ ɾΞϯνύλʔϯ ɹωΠςΟϒػೳฤ ɹϥΠϑαΠΫϧฤ ɹϨΠΞ΢τฤ ɾ·ͱΊ

  11. 11 ࠓ೔͢Δ࿩ ɾେ·͔ͳJ04ͱ"OESPJEͷҧ͍ ɾJ04Ͱ͸༰қʹ࣮૷Ͱ͖Δ͕"OESPJEͰ͸ͦ͏΋͍͔ͳ͍࿩ ɾˢͷٯ

  12. 12 ࠓ೔͠ͳ͍࿩ ɾҰํͷ04ʹ߹Θͤͨ࢓༷ʹແཧ໼ཧ͚ۙͮͨ࿩ ɾͦΕͧΕͷΨΠυϥΠϯͷৄࡉͳ࿩ ɾϥΠϑαΠΫϧͷৄ͍͠࿩ ɾ%BUB#JOEJOHʹ·ͭΘΔ࿩ ͔ͨͬͨ͠ʜ

  13. Ξϯνύλʔϯ ωΠςΟϒػೳฤ

  14. 14 ΞϯνύλʔϯʙωΠςΟϒػೳฤʙ %5PVDI Έͳ͞Μɺ"OESPJEΛڧ͘ԡͯ͠Έ·͠ΐ͏ʂ -FU`T%5PVDIʂʂ

  15. 15 ΞϯνύλʔϯʙωΠςΟϒػೳฤʙ #SPLFO ˞͚ͬͯ͠ϚωΛ͠ͳ͍Ͱ͍ͩ͘͞

  16. 16 ΞϯνύλʔϯʙωΠςΟϒػೳฤʙ ɾ%5PVDI͸J1IPOFTҎ߱ͷ୺຤Ͱ࣮૷ ɾ"OESPJE͸Ͱ͸ඇରԠ μϒϧλοϓPSϩϯάλοϓͰ౷ҰͰ ͖ΔͷͰ͋Ε͹"OESPJEΛߟ͑Δͱ౷Ұ͠ ͯ͋͛Δํ๏΋ߟྀ͢Δ

  17. 17 ΞϯνύλʔϯʙωΠςΟϒػೳฤʙ ɾܾࡁपลͰ͸/'$౥ࡌະ౥ࡌͷόϥπΩ͕ ͋Δ ɾ"7'PVOEBUJPOͱ#BSDPEF"1*Ͱ࣮૷Մೳ

  18. 18 ΞϯνύλʔϯʙωΠςΟϒػೳฤʙ ɾωΠςΟϒػೳʹ͸ػछɾ୺຤ґଘ͕ܹ͍͠ ɾJ04"OESPJEͰՄೳෆՄೳͳػೳΛͳͨ͘͢Ίɺ ͋͘·Ͱ΋ิࠤతͳػೳͰ࢖༻

  19. Ξϯνύλʔϯ ϥΠϑαΠΫϧฤ

  20. 20 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ 7JFX$POUSPMMFSϥΠϑαΠΫϧ ͓ೃછΈͷϥΠϑαΠΫϧ

  21. 21 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ "DUJWJUZϥΠϑαΠΫϧ ɾPO$SFBUF ͔Β࢝·Δ ɾ"DUJWJUZ͕ఀࢭঢ়ଶ ϝϞϦʹ͸࢒͍ͬͯΔ ঢ়ଶ͔Β෮ؼ͢ΔͱPO3FTUBSU ͕ίʔϧ͞ ΕɺPO4UBSU

    ͔ΒϥΠϑαΠΫϧ͕࢝·Δ
  22. 22 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ 'SBHNFOUϥΠϑαΠΫϧ ɾ"DUJWJUZͷPO$SFBUF ͕ίʔϧ͞Εͨޙʹ 'SBHNFOUͷPO"UUBDI dPO4UBSU ·ͰҰؾ ʹίʔϧ͞ΕΔ ɾىಈ͸"DUJWJUZ'SBHNFOUɺऴྃ͸

    'SBHNFOU"DUJWJUZ
  23. 23 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ "DUJWJUZͷϥΠϑαΠΫϧΠϕϯτͷ 'SBHNFOUͷϥΠϑαΠΫϧΠϕϯτ͸جຊ తʹަ͍ࠩͯ͠Δ

  24. 24 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ ྫ͑͹ɺ ɾWJFX%JE%JTBQQFBS Ͱ࣮૷͞Εͨॲཧ͸"OESPJEͰ͸Ͳ͜Ͱߦ͑͹ྑ͍ʁ ɾPO4UPQͱPO%FTUSPZͰॲཧ͕ҟͳΔ৔߹͸J04Ͱ͸Ͳ͜ͰΘ͚Ε͹ྑ͍ʁ

  25. 25 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ ྫ͑͹ɺ ɾWJFX%JE%JTBQQFBS Ͱ࣮૷͞Εͨॲཧ͸"OESPJEͰ͸Ͳ͜Ͱߦ͑͹ྑ͍ʁ ɾPO4UPQͱPO%FTUSPZͰॲཧ͕ҟͳΔ৔߹͸J04Ͱ͸Ͳ͜ͰΘ͚Ε͹ྑ͍ʁ J04͸දࣔ͞Ε͍ͯΔ͔͞Ε͍ͯͳ͍͔ʹؔ৺͕ߴ͍͕ɺ"OESPJE͸"DUJWJUZ 'SBHNFOU ͕ഁغ͞Ε͔ͨͲ͏͔΍ΞϓϦࣗମͷঢ়ଶ ϝϞϦ্

    ʹ΋ؔ৺͕͋Δ
  26. 26 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ ྫɿΞϓϦىಈ࣌ ɾΞϓϦىಈ࣌ʹ͋ΔಛఆͷॳظԽॲཧΛߦΘͤΔ 'JSFCBTFϩάΠϯ΍1FSNJTTJPOऔಘͳͲ 

  27. 27 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ  ΞϓϦىಈ  ৭ʑͳը໘Λ։͘  ϗʔϜϘλϯΛλοϓ "DUJWJUZͷੜଘ͕อো͞Εͳ͍ɺ࠷ѱͷ৔߹1SPDFTT͕ࢮΜͰ͍Δ ྫɿΞϓϦىಈ࣌

  28. 28 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ  ΞϓϦىಈ  ৭ʑͳը໘Λ։͘  ໭ΔϘλϯ࿈ଧ 1SPDFTT͸ੜ͖͍ͯΔɺ'JSFCBTFͷϩάΠϯ৘ใͳͲ΋ੜ͖͍ͯΔ ྫɿΞϓϦىಈ࣌

  29. 29 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ  ΞϓϦىಈ  ৭ʑͳը໘Λ։͘  ϗʔϜϘλϯΛλοϓ  3FDFOU͔ΒΞϓϦΛ࡟আ

    "OESPJE͸1SPDFTTͷ࡟আ͕อো͞Εͳ͍ ྫɿΞϓϦىಈ࣌
  30. 30 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ "OESPJEͷىಈͱ͸ʁ ɾ"DUJWJUZ΍ΞϓϦͷ1SPDFTT͸୺຤ࣗମͷϝϞϦ΍ੑೳʹґଘ͢Δ͜ͱ΋͋Δ ɾ"DUJWJUZج४ͳͷ͔ΞϓϦࣗମͷ1SPDFTTج४ͳͷ͔Λ໌֬ʹ͢Δඞཁ͕͋Δ

  31. 31 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ "OESPJEͷىಈͱ͸ʁ ɾ"DUJWJUZ΍ΞϓϦͷ1SPDFTT͸୺຤ࣗମͷϝϞϦ΍ੑೳʹґଘ͢Δ͜ͱ΋͋Δ ɾ"DUJWJUZج४ͳͷ͔ΞϓϦࣗମͷ1SPDFTTج४ͳͷ͔Λ໌֬ʹ͢Δඞཁ͕͋Δ "OESPJEͷىಈͱ͸ ʮىಈखஈʯͱ ʮىಈ࣌ͷঢ়گʯʹΑͬͯύλʔϯ͕ܾఆ͢Δ

  32. 32 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ "OESPJEͷը໘ճస 08-28 14:06:27.420 16839-16839/bio.enoque.enoque_android D/debug: onCreate() 08-28 14:06:27.436

    16839-16839/bio.enoque.enoque_android D/debug: onStart() 08-28 14:06:27.437 16839-16839/bio.enoque.enoque_android D/debug: onResume() 08-28 14:06:31.625 16839-16839/bio.enoque.enoque_android D/debug: onPause() 08-28 14:06:31.626 16839-16839/bio.enoque.enoque_android D/debug: onStop() 08-28 14:06:31.626 16839-16839/bio.enoque.enoque_android D/debug: onDestroy() 08-28 14:06:31.833 16839-16839/bio.enoque.enoque_android D/debug: onCreate() 08-28 14:06:31.835 16839-16839/bio.enoque.enoque_android D/debug: onStart() 08-28 14:06:31.835 16839-16839/bio.enoque.enoque_android D/debug: onResume()
  33. 33 ΞϯνύλʔϯʙϥΠϑαΠΫϧฤʙ "OESPJEͷը໘ճస 08-28 14:06:27.420 16839-16839/bio.enoque.enoque_android D/debug: onCreate() 08-28 14:06:27.436

    16839-16839/bio.enoque.enoque_android D/debug: onStart() 08-28 14:06:27.437 16839-16839/bio.enoque.enoque_android D/debug: onResume() 08-28 14:06:31.625 16839-16839/bio.enoque.enoque_android D/debug: onPause() 08-28 14:06:31.626 16839-16839/bio.enoque.enoque_android D/debug: onStop() 08-28 14:06:31.626 16839-16839/bio.enoque.enoque_android D/debug: onDestroy() 08-28 14:06:31.833 16839-16839/bio.enoque.enoque_android D/debug: onCreate() 08-28 14:06:31.835 16839-16839/bio.enoque.enoque_android D/debug: onStart() 08-28 14:06:31.835 16839-16839/bio.enoque.enoque_android D/debug: onResume() ͜͜Ͱը໘ճస
  34. Ξϯνύλʔϯ ϨΠΞ΢τฤ

  35. 35 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ /BWJHBUJPO$POUSPMMFS self.navigationController? .pushViewController(nextViewController, animated: true) J04ը໘ભҠ 1SFTFOU self.present(nextViewController,

    animated: true, completion: nil)
  36. 36 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ *OUFOU val intent = Intent(this, LoginActivity::class.java) startActivity(intent) "OESPJEͷը໘ભҠ

  37. 37 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ ɾJ04ͷ̎௨Γͷը໘ભҠͷΞχϝʔγϣϯʹ ҙຯΛ࣋ͯͤͯ͠·ͬͨέʔε ɾ"OESPJEͷ*OUFOUʹΑΔը໘ભҠ͸جຊతʹ ௨Γ ɾ*OUFOUͰ͜ΕΒͷΞχϝʔγϣϯΛ࢖͍෼͚ Δͷ͸໘౗ *OUFOUͷ֦ுؔ਺͕͋Ε͹ʜ 

  38. 38 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ Α͋͘ΔϨΠΞ΢τɻ ͜Εɺҙ֎ͱͦΕͧΕେมͳͱ͕͋͜ Γ·͢ɻ

  39. 39 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ J04 6*5BC7JFX $POUSPMMFS 6*-BCFM 6*7JFX6*4DSPMM7JFX 6*1BHF7JFX$POUSPMMFS  6*$POUBJOFS7JFX

  40. 40 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ J04 6*5BC7JFX $POUSPMMFS 6*-BCFM 6*7JFX6*4DSPMM7JFX 6*1BHF7JFX$POUSPMMFS  6*$POUBJOFS7JFX

    େมͳͷ͜ͷ෦෼
  41. 41 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ "OESPJE 5BC-BZPVU 7JFX1BHFS "DUJWJUZ 'SBHNFOU 5BC-BZPVU༻  

    'SBHNFOU 7JFX1BHFS༻
  42. 42 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ "OESPJE 5BC-BZPVU 7JFX1BHFS "DUJWJUZ 'SBHNFOU 5BC-BZPVU༻  

    'SBHNFOU 7JFX1BHFS༻ େมͳͷ͜ͷ෦෼
  43. 43 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ private fun tabSelectedListener() { val tabLayout = findViewById<TabLayout>(R.id.HomeTabLayoutID)

    tabLayout.getTabAt(0)!!.setIcon(R.mipmap.ic_home_selected) tabLayout.getTabAt(1)!!.setIcon(R.mipmap.ic_search) val fragmentManager = supportFragmentManager val transaction = fragmentManager.beginTransaction() transaction.add(R.id.ContainerID, AccountFragment()).commit() tabLayout.addOnTabSelectedListener(object: TabLayout.OnTabSelectedListener { override fun onTabSelected(tab: TabLayout.Tab) { when(tab.position) { 0 -> { supportActionBar?.setDisplayHomeAsUpEnabled(false) tabLayout.getTabAt(0)!!.setIcon(R.mipmap.ic_home_selected) val fragmentManager = supportFragmentManager val transaction = fragmentManager.beginTransaction() transaction.replace(R.id.ContainerID, AccountFragment()).commit() } 1 -> { supportActionBar?.setDisplayHomeAsUpEnabled(false) tabLayout.getTabAt(1)!!.setIcon(R.mipmap.ic_search_selected) val fragmentManager = supportFragmentManager val transaction = fragmentManager.beginTransaction() transaction.replace(R.id.ContainerID, MapFragment()).commit() } } } "DUJWJUZ
  44. 44 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ private fun tabSelectedListener() { val tabLayout = findViewById<TabLayout>(R.id.HomeTabLayoutID)

    tabLayout.getTabAt(0)!!.setIcon(R.mipmap.ic_home_selected) tabLayout.getTabAt(1)!!.setIcon(R.mipmap.ic_search) val fragmentManager = supportFragmentManager val transaction = fragmentManager.beginTransaction() transaction.add(R.id.ContainerID, AccountFragment()).commit() tabLayout.addOnTabSelectedListener(object: TabLayout.OnTabSelectedListener { override fun onTabSelected(tab: TabLayout.Tab) { when(tab.position) { 0 -> { supportActionBar?.setDisplayHomeAsUpEnabled(false) tabLayout.getTabAt(0)!!.setIcon(R.mipmap.ic_home_selected) val fragmentManager = supportFragmentManager val transaction = fragmentManager.beginTransaction() transaction.replace(R.id.ContainerID, AccountFragment()).commit() } 1 -> { supportActionBar?.setDisplayHomeAsUpEnabled(false) tabLayout.getTabAt(1)!!.setIcon(R.mipmap.ic_search_selected) val fragmentManager = supportFragmentManager val transaction = fragmentManager.beginTransaction() transaction.replace(R.id.ContainerID, MapFragment()).commit() } } } "DUJWJUZ
  45. 45 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ val fragmentManager = supportFragmentManager val transaction = fragmentManager.beginTransaction()

    transaction.add(R.id.ContainerID, AccountFragment()).commit() tabLayout.addOnTabSelectedListener(object: TabLayout.OnTabSelectedListener { override fun onTabSelected(tab: TabLayout.Tab) { when(tab.position) { 0 -> { supportActionBar?.setDisplayHomeAsUpEnabled(false) tabLayout.getTabAt(0)!!.setIcon(R.mipmap.ic_home_selected) val fragmentManager = supportFragmentManager val transaction = fragmentManager.beginTransaction() transaction.replace(R.id.ContainerID, AccountFragment()).commit() } … } "DUJWJUZ
  46. 46 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ private fun settingPager() { this.frame?.let { val viewPager

    = it.findViewById<ViewPager>(R.id.ViewPagerID) val fragmentPagerAdapter = AccountPagerAdapter(this.getChildFragmentManager()) viewPager.adapter = fragmentPagerAdapter val tabLayout = it.findViewById<TabLayout>(R.id.TabLayoutID) tabLayout.setupWithViewPager(viewPager) tabLayout.getTabAt(0)!!.setText("ޚगҹҰཡ") tabLayout.getTabAt(1)!!.setText("ઃఆ") } } 'SBHNFOU ୈҰ֊૚
  47. 47 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ private fun settingPager() { this.frame?.let { val viewPager

    = it.findViewById<ViewPager>(R.id.ViewPagerID) val fragmentPagerAdapter = AccountPagerAdapter(this.getChildFragmentManager()) viewPager.adapter = fragmentPagerAdapter val tabLayout = it.findViewById<TabLayout>(R.id.TabLayoutID) tabLayout.setupWithViewPager(viewPager) tabLayout.getTabAt(0)!!.setText("ޚगҹҰཡ") tabLayout.getTabAt(1)!!.setText("ઃఆ") } } 'SBHNFOU ୈҰ֊૚
  48. 48 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ 'SBHNFOUJO'SBHNFOU 7JFX1BHFS͕ωετ͍ͯͯ͠'SBHNFOUΛ਌֊૚ͱͯ͠࢖༻͍ͯ͠Δ৔߹ɺ 'SBHNFOU1BHFS"EBQUFSͷίϯετϥΫλʹҾ਺ͱͯ͠౉͢ 'SBHNFOU.BOBHFS͸HFU$IJME'SBHNFOU.BOBHFSΛ౉͞ͳ͚Ε͹ͳΒͳ ͍

  49. 49 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ class AccountPagerAdapter(fragmentManager: FragmentManager): FragmentPagerAdapter(fragmentManager) { override fun getCount():

    Int { return 2 } override fun getItem(position: Int): Fragment { when (position) { 0 -> { return AccountMarksFragment() } 1 -> { return SettingFragment() } } return Fragment() } } 'SBHNFOU1BHFS"EBQUFS
  50. 50 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ class AccountPagerAdapter(fragmentManager: FragmentManager): FragmentPagerAdapter(fragmentManager) { override fun getCount():

    Int { return 2 } override fun getItem(position: Int): Fragment { when (position) { 0 -> { return AccountMarksFragment() } 1 -> { return SettingFragment() } } return Fragment() } } 'SBHNFOU1BHFS"EBQUFS HFU$IJME'SBHNFOU.BOBHFS͡Ό ͳ͍ͱ5BCͰ'SBHNFOUΛ཭Εͨ ࣌ʹHFU*UFN ͕ݺ͹Εͳ͍
  51. 51 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ class AccountMarksFragment : Fragment() { private var frame:

    View? = null override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { this.frame = inflater!!.inflate(R.layout.fragment_account_marks, container, false) return this.frame } override fun onStart() { super.onStart() this.onMarkPostButtonClick() } private fun onMarkPostButtonClick() { MarkPostButtonID.setOnClickListener { val activity = activity as AccountActivity val intent = Intent(activity, MarkPostActivity::class.java) startActivity(intent) } } } 'SBHNFOU ୈೋ֊૚
  52. 52 ΞϯνύλʔϯʙϨΠΞ΢τฤʙ class AccountMarksFragment : Fragment() { private var frame:

    View? = null override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { this.frame = inflater!!.inflate(R.layout.fragment_account_marks, container, false) return this.frame } override fun onStart() { super.onStart() this.onMarkPostButtonClick() } private fun onMarkPostButtonClick() { MarkPostButtonID.setOnClickListener { val activity = activity as AccountActivity val intent = Intent(activity, MarkPostActivity::class.java) startActivity(intent) } } } 'SBHNFOU ୈೋ֊૚ PO$SFBUF7JFX ͩͱ8JEHFU ؔ࿈͕ੜ੒͞Ε͍ͯͳ͍
  53. ·ͱΊ

  54. 54 ·ͱΊ ɾಉ͡εϚϗΞϓϦͰ΋֤ϓϥοτϗʔϜͷ։ൃऀଆ͔Β͢Δͱߟྀ͠ͳ͚Ε͹ ͳΒͳ͍఺͕ͨ͘͞Μ ɾৄࡉઃܭ΍޻਺Λܾఆ͢Δஈ֊Ͱػೳɾ࣮૷୯ҐͰͲΕ͙Β͍ͷόϥπΩ͕ग़ Δ͔͸͋Δఔ౓೺Ѳͯ͠੝Γࠐ·ͳ͍ͱ͍͚ͳ͍ ɾগ͠Ͱ΋"OESPJEΛ஌͓͍ͬͯͯ͋͛Δ͚ͩͰɺ"OESPJEΤϯδχΞ΋৺ͷΏ ͱΓ͕Ͱ͖ΔͷͰɺੋඇ"OESPJE΋஌ͬͯ"OESPJEΤϯδχΞ͞Μͱ஥ྑ͘ա͝ ͠·͠ΐ͏ʂʂ

  55. ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠