
Evgeny Yolchev rsi ãiOSããŒã ã®ãªãŒãKODE
æè¿ãç§ã¯DIã«ã€ããŠãŸããŸãè³ã«ããŸããã 圌ã¯ã®ãŒã¯å€§åŠã®ç§ã®åŠçã«èå³ãããããã£ããã«ãŒã ã§èšåãããŠããŸãã ãã®ãã¿ãŒã³ã¯è¥ãã¯ãããŸããããå€ãã®äººã¯ãããæ£ããç解ããŠããŸããã
å€ãã®å ŽåãDIã¯å°é¢šãswinjectãªã©ã®ãã¬ãŒã ã¯ãŒã¯ãæããŸãã ãã®èšäºã§ã¯ãDIå®è£
ã®ååãšIoCã®ååã詳现ã«åæããŸãã èå³ãããã°ãç«ã®äžã§ãé¡ãããŸãã
DIïŒäŸåæ§æ³šå
¥ïŒã¯ããœãããŠã§ã¢ã³ã³ããŒãã³ãã«å€éšäŸåæ§ãæäŸããããã»ã¹ã§ãã äŸåé¢ä¿ç®¡çã«é©çšãããå ŽåããIoCãã®ç¹å®ã®åœ¢åŒã§ãã å¯äžã®è²¬ä»»ã®ååã«å®å
šã«åŸã£ãŠããªããžã§ã¯ãã¯ããã®äžè¬çãªã¡ã«ããºã ã®ããã«ç¹å¥ã«èšèšãããå€éšã«å¿
èŠãªäŸåé¢ä¿ãæ§ç¯ããããšã«æ³šæãæããŸãã
IoCïŒInversion of ControlïŒã¯ãã³ã³ãã¥ãŒã¿ãŒããã°ã©ã ã®ãªã³ã¯ïŒåéïŒãæžããããã«äœ¿çšããããªããžã§ã¯ãæåããã°ã©ãã³ã°ã®éèŠãªååã§ãã
ãã®èšäºã¯DIã«é¢ãããã®ã§ãããDIã«ã€ããŠã¯èª¬æããŸããããDIã¯IoCã®çš®é¡ã®1ã€ã«ããããå
šäœåã確èªããå¿
èŠããããããIoCã䜿çšããŸãã
IoC
ãŸãã管çãšã¯äœããææ¡ããŸãããã æãåçŽãªäŸã§ããã³ã³ãœãŒã«ãHello worldããã芧ãã ããã
let firstWord = «hello» let secondWord = "world!" let phrase = firstWord + " " + secondWord print(phrase)
ãã®äŸã§ã¯ãã³ãã³ãã¯æååãªãã©ã«ãšå€æ°ã§è¡šãããããŒã¿ãæäœããŸãã ãã®æœè±¡åã¬ãã«ã§ã¯ãã以äžå¶åŸ¡ã§ããŸããããäžé
æŒç®åã䜿çšããŠè¿œå ã§ããŸãã
let number = arc4random_uniform(1) let firstWord = number == 0 ? "hello" : "bye" let secondWord = "world!" let phrase = firstWord + " " + secondWord print(phrase)
ã³ãŒãã¯ãããŸãã«ãªããä¹±æ°ã«å¿ããŠã³ã³ãœãŒã«ã®è¡ãå€ãããŸãã èšãæããã°ãããŒã¿ãããã°ã©ã ãé§åããŸãã ããã¯ãå¶åŸ¡å転ã®æãäžè¬çã§æãåçŽãªäŸã§ãã
å
žåçãªiOSã¢ããªã±ãŒã·ã§ã³ã§ã¯ãå¶åŸ¡ã¯ã©ãã«ã§ããããŸãã ã·ã¹ãã ããŠãŒã¶ãŒããµãŒããŒãã¢ããªã±ãŒã·ã§ã³ãå¶åŸ¡ããŸãã ã¢ããªã±ãŒã·ã§ã³ã¯ããµãŒããŒããŠãŒã¶ãŒãããã³ã·ã¹ãã ã管çããŸãã ã³ãŒãã«ã¯ãçžäºã«å¶åŸ¡ããèšå€§ãªæ°ã®ãªããžã§ã¯ããå«ãŸããŠããŸãã ããšãã°ã AuthViewControllerã¯ã©ã¹ã®ãªããžã§ã¯ãã¯ã AuthServiceã¯ã©ã¹ã®ãªããžã§ã¯ããå¶åŸ¡ã§ããŸãã
ãã®ãããªæœèšç®¡çã¯ãããã€ãã®åŽé¢ããæ§ç¯ãããŸãã æåã«ã AuthViewControllerã¯AuthServiceã¡ãœãããåŒã³åºãã次ã«ããããäœæããŸãã ããã¯ãã¹ãŠããªããžã§ã¯ãã®é«ãæ¥ç¶æ§ã«ã€ãªãããŸã; AuthViewControllerã®äœ¿çšã¯AuthServiceãªãã§ã¯äžå¯èœã«ãªããŸãã ããã¯äŸåé¢ä¿ãšåŒã°ãã AuthViewControllerã¯AuthServiceã«å®å
šã«äŸåããŠããŸã ã
ãã®ãããªäŸåé¢ä¿ã«åé¡ã¯ãªããšèããããŠããŸãã ååãšããŠãã³ã³ãããŒã©ãŒã¯åå©çšããããåžžã«ã¢ããªã±ãŒã·ã§ã³ããµããŒããããµãŒãã¹ãšé£æºããŸãã ããããé·å¯¿åœã®ã¢ããªã±ãŒã·ã§ã³ããµããŒãããŠãã人ã
ã¯ããããããã§ã¯ãªãããšãç¥ã£ãŠããŸãã èŠä»¶ã¯åžžã«å€åããŠããŸãããã°ãèŠã€ãããããŒãå€æŽããåèšèšãè¡ããŸãã åæã«ãURLSessionã®åãªãã©ãããŒã§ããããã€ãã®ãã¿ã³ãšãµãŒãã¹ãåããè€æ°ã®ã³ã³ãããŒã©ãŒãããã¢ããªã±ãŒã·ã§ã³ãè€éãªå ŽåãäŸåé¢ä¿ã«inããŠããŸãã ã¯ã©ã¹éã®äŸåé¢ä¿ã¯Webã圢æãã埪ç°çãªäŸåé¢ä¿ãèŠã€ããããšãã§ããŸãã ã¯ã©ã¹ãå€æŽããããšã¯ã§ããŸãããã¯ã©ã¹ã®äœ¿çšæ¹æ³ãšäœ¿çšå Žæãæ確ã§ã¯ãªããããå€ãã¡ãœãããå€æŽãããããæ°ããã¡ãœãããäœæããæ¹ãç°¡åã§ãã ã¯ã©ã¹ã眮ãæãããšçã¿ã«å€ãããŸãã ã³ã³ã¹ãã©ã¯ã¿ãŒã®åŒã³åºãã¯ããŸããŸãªã¡ãœããã«ãã£ãŠåæ£ãããŠããããããã®ã¡ãœãããå€æŽããå¿
èŠããããŸãã æçµçã«ãäœãèµ·ãã£ãŠããã®ãç解ã§ããªããªããã³ãŒãã¯ãã¬ãŒã³ããã¹ãã«å€ãããæ€çŽ¢æ©èœã䜿çšããŠããã®ããã¹ãå
ã®åèªãŸãã¯æã眮ãæããã³ã³ãã€ã©ãšã©ãŒã®ã¿ããã§ãã¯ãå§ããŸãã
ã€ãã³ãã®ãã®çµæãé²ãããã«ãå€ãã®ååãšæè¡ãçºæãããŸããã ããšãã°ãSOLIDã®ååã®1ã€ã§ããDIPã®ååã§ã¯ãã¡ãœãããåŒã³åºããšãã«æ¥ç¶ãæžããæ¹æ³ã説æããŠããŸããããã¯IoCã§ãã
DIPïŒDependency Inversion PrincipleïŒã¯ã5ã€ã®SOLIDååã®1ã€ã§ãã
èšèé£ãïŒ
äžäœã¢ãžã¥ãŒã«ã¯äžäœã¢ãžã¥ãŒã«ã«äŸåããªãã§ãã ããã ã©ã¡ãã®ã¿ã€ãã®ã¢ãžã¥ãŒã«ãæœè±¡åã«äŸåããå¿
èŠããããŸãã
æœè±¡åã¯è©³çŽ°ã«äŸåãã¹ãã§ã¯ãããŸããã 詳现ã¯æœè±¡åã«äŸåããå¿
èŠããããŸãã
ããããããã§ãã誰ããã IoC ããšèšããšããäŸåé¢ä¿ãäœæãããšãã®å¶åŸ¡ã®å転ãæå³ããŸãã ããã«ããã®æå³ã§ã®ã¿äœ¿çšããŸãã ã¡ãªã¿ã«ãDIPã¯IoCãªãã§å®è£
ããããšã¯ã»ãšãã©äžå¯èœã§ããããã®éã¯äžå¯èœã§ãã IoCã䜿çšããŠããDIPãžã®æºæ ã¯ä¿èšŒãããŸããã å¥ã®éèŠãªãã¥ã¢ã³ã¹ã DIPãšDIã¯2ã€ã®ç°ãªãååã§ãã
IoCãžã®éäž
å®éãIoCã¯éåžžã«åçŽãªæŠå¿µã§ãããå€ãã®æç®ãèªãå¿
èŠã¯ãããŸãããæ°å¹Žéããããã«è¡ã£ãŠZenãç解ãã䜿ãå§ããããšãã§ããŸãã
äŸãšããŠããéšå£«ãïŒ Knight ïŒãšãã®ãé§ãïŒ Armor ïŒã®ã¯ã©ã¹ãæ€èšããŸãããã¹ãŠã®ã¯ã©ã¹ã以äžã«ç€ºããŸãã

ããã§ã¯ã Armorã¯ã©ã¹ã®å®è£
ãèŠãŠã¿ãŸãããã
class Armor { private var boots: Boots? private var pants: Pants? private var belt: Belt? private var chest: hest? private var bracers: Bracers? private var gloves: Gloves? private var helmet: Helmet? func configure() { self.boots = Boots() self.pants = Pants() self.belt = Belt() self.chest = hest() self.bracers = Bracers() self.gloves = Gloves() self.helmet = Helmet() } }
ãšéšå£«
class Knight { private var armor: Armor? func prepareForBattle() { self.armor = Armor() self.armor.configure() } }
äžèŠããã¹ãŠãæ£åžžã§ãã ãã€ããå¿
èŠãªå Žåã¯ãäœæããŸãã
let knight = Knight()
ããããããã»ã©åçŽã§ã¯ãããŸããã æ®å¿µãªããã代çã®äŸã§ã¯ããã®ã¢ãããŒãããããããã¹ãŠã®èŠçãäŒããããšã¯ã§ããŸããã
ã¯ã©ã¹ã¯äºãã«ã¯ãã ä»ããããŠããŸãã Armor
ã¯make
ã¡ãœããã§7ã€ã®ã¯ã©ã¹ãäœæããŸãã ããã«ãããã¯ã©ã¹ã骚åãããŸãã ãã®ã¢ãããŒãã§ã¯ãã¯ã©ã¹ãäœæããå Žæãšæ¹æ³ã決å®ããããšã¯ã§ããŸããã ã¢ãŒããŒããç¶æ¿ããŠãããšãã°ååŒçšã®ã¢ãŒããŒãäœæããŠãã«ã¡ããã眮ãæããå¿
èŠãããå Žåã¯ãã¡ãœããå
šäœãåå®çŸ©ããå¿
èŠããããŸãã
ãã®ã¢ãããŒãã®å¯äžã®ãã©ã¹ã¯ãã¯ã©ã¹ãäœæãããšãã«å°æ¥ã«ã€ããŠèããå¿
èŠããªããããã³ãŒãã®èšè¿°é床ã§ãã
ããã人çã§ã©ã®ããã«èŠãããã®å°ããªäŸã§ãïŒ
class FightViewController: BaseViewController { var titleLabel: UIView! var knightList: UIView! override func viewDidLoad() { super.viewDidLoad() self.title = // , // let backgroundView = UIView() // self.view.addSubview(backgroundView) // backgroundView.backgroundColor = UIColor.red // backgroundView.translatesAutoresizingMaskIntoConstraints = false backgroundView.translatesAutoresizingMaskIntoConstraints = false backgroundView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true backgroundView.topAnchor.constraint(equalTo: topAnchor).isActive = true backgroundView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true backgroundView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true let title = Views.BigHeader.View() self.titleLabel = title title.labelView.text = self.view.addSubview(title) title.translatesAutoresizingMaskIntoConstraints = false title.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true title.topAnchor.constraint(equalTo: topAnchor).isActive = true title.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true title.heightAnchor.constraint(equalToConstant: 56).isActive = true let knightList = Views.DataView.View() self.knightList = knightList knightList.titleView.text = knightList.dataView.text = self.view.addSubview(knightList) knightList.translatesAutoresizingMaskIntoConstraints = false knightList.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true knightList.topAnchor.constraint(equalTo: title.topAnchor).isActive = true knightList.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true knightList.heightAnchor.constraint(equalToConstant: 45).isActive = true } }
ãã®ãããªã³ãŒãã¯ãä»ã®äººã®ãããžã§ã¯ãã§ç°¡åã«èŠã€ããããšãã§ããŸãã 圌ã¯ãä»»æã®å Žæã«äŸåé¢ä¿ã¯ã©ã¹ãäœæããã®ã¯è¯ãèãã§ã¯ãªãããšãå®å
šã«ç€ºããŠããŸãã ããã«ãé§ãšã¯ç°ãªããããã®èŠçŽ ã¯äœæãããã ãã§ãªããæ§æãããé
眮ãããŸãã ã³ãŒãã¯æ··ä¹±ã«å€ãããŸããã
ããã¯ã©ã®ããã«æ¹åã§ããŸããïŒ ãå·¥å Žã¡ãœããããã¿ãŒã³ã䜿çšããŸãã ãã¹ãŠã®åé¡ã解決ããããã§ã¯ãããŸããããã¯ã©ã¹ãããæè»ã«ããŸãã
ä»®æ³ã¡ãœãããšãåŒã°ãããã¡ã¯ããªã¡ãœããã¯ãã¯ã©ã¹ãã€ã³ã¹ã¿ã³ã¹åããããã®ã€ã³ã¿ãŒãã§ã€ã¹ããµãã¯ã©ã¹ã«æäŸããäžè¬çãªãã¶ã€ã³ãã¿ãŒã³ã§ãã
class Armor { private var boots: Boots? private var pants: Pants? func configure() { self.boots = makeBoots() self.pants = makePants() } func makeBoots() -> Boots { return Boots() } func makePants() -> Pants { return Pants() } }
äŸåé¢ä¿ã®äœæã¯å¥ã®æ¹æ³ã§è¡ãããŸãã ã¯ã©ã¹ããžãã¯ã«æå·ãäžããããšãªããç°¡åã«èŠã€ããŠå€æŽã§ããŸãã ç¶æ¿ã§ã¯ãããããåå®çŸ©ããŠãäŸåé¢ä¿ãåå®çŸ©ã§ããŸãã
ããã§ããã¯ã©ã¹ã¯äŸåé¢ä¿ã®äœæã®è©³çŽ°ãç¥ãå¿
èŠã¯ãªãããããã䜿çšããã ãã§ãã ããã«å¯ŸåŠããæ¹æ³ã¯ïŒ çæããžãã¯ãã¯ã©ã¹ããããé«ãã¬ãã«ã«åŒãäžããå¿
èŠããããŸãã
çæããžãã¯ã¯ãã¯ã©ã¹ãŸãã¯æ§é ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããã³ãŒãã§ãã ã€ãŸãããªããžã§ã¯ããçæããã³ãŒãã
class Armor { private var boots: Boots? private var pants: Pants? func configure(boots: Boots?, pants: Pants?) { self.boots = boots self.pants = pants } }
çŸåšã Armor
ã¯ã©ã¹ã«ã¯ãäŸåé¢ä¿ãã©ã®ããã«äœæãããããããããŸããããããã¯åã«åŒæ°ãšããŠæž¡ãããŸãã ããã«ãããæ倧éã®æè»æ§ãåŸãããŸãã ã¯ã©ã¹ããããã³ã«ã«çœ®ãæããå®è£
ã®è©³çŽ°ãå®å
šã«ç¡èŠããããšãã§ããŸãã
ããããç§ãã¡ã®Knight
ã¯ã©ã¹ã§ã¯ããŸããããŸããã
class Knight { private var armor: Armor? func preapreForBattle() { self.armor = Armor() let boots = makeBoots() let pants = makePants() self.armor?.make(boots: boots, pants: pants) } func makeBoots() -> Boots { return Boots() } func makePants() -> Pants { return Pants() } }
圌ã¯åœŒã®é§ã®ãã¹ãŠã®éšåãäœæããŸãã ç§ãã¡ã®éšå£«ã¯åœŒèªèº«ã®éå¶å±ã§ãããšèšããŸãã
ããã¯ééã£ãŠããŸãããã€ãã¯ã¿ã¹ã¯ã¬ãã«ã§ã¯ãªããè£
ç²ãåœé ããã¹ãã§ã¯ãããŸããã åã³çæããžãã¯ãããé«ãã¬ãã«ã«åŒãäžããããšãã§ããŸãããã°ã©ãã®äžéšã«ããã¯ã©ã¹ã¯äŸåé¢ä¿ãäœæããããã®å·šå€§ãªãã³ãã«ãªããŸãã
å¥ã®çæãã¿ãŒã³ãæå©ã«æ¥ãã§ããã-ãå·¥å Žãã
ãã¡ã¯ããªãŒïŒè±èªã®ãã¡ã¯ããªãŒïŒ-ä»ã®ãªããžã§ã¯ããäœæãããªããžã§ã¯ãã
è£
ç²ã®äžéšãäœæããŠ1ã€ã®ã»ããã«ãŸãšãããã©ãŒãžãæ§ç¯ããŸãã
class Forge { func makeArmor() -> Armor { let armor = Armor() armor.boots = makeBoots() armor.pants = makePants() return armor } func makeBoots() -> Boots { return Boots() } func makePants() -> Pants { return Pants() } }
Armor
ã¯ã©ã¹ãšKnight
ã¯ã©ã¹ã¯çæããžãã¯ãåãé€ããç°¡æœã«èŠããŸãã
class Armor { var boots: Boots? var pants: Pants? } class Knight { var armor: Armor? }
ããã§ããå·¥å ŽãããäŸåé¢ä¿ãã©ã®ããã«ãã©ãã§ããã€ååŸããŠã¯ã©ã¹ã«è»¢éããããšããåé¡ã«çŽé¢ããŠããŸãã ãããŠãããã¯ã€ãã«DIãšSLã®æŠå¿µã«å°éããããšãæå³ããŸãã
ãµãŒãã¹ãã±ãŒã¿ãŒïŒSLïŒ
ãã®ãã¿ãŒã³ããå§ããŸãããã ãŸããããã·ã³ãã«ã§ãã 第äºã«ãå€ãã®äººã
ã¯ãããDIã§ãããšèããŠããŸãããããã§ã¯ãããŸããã
SLïŒãµãŒãã¹ãã±ãŒã¿ãŒïŒã¯ã匷åãªæœè±¡åã¬ãã«ã§ãµãŒãã¹ãååŸããããšã«é¢é£ããããã»ã¹ãã«ãã»ã«åããããã®ãœãããŠã§ã¢ã®éçºã§äœ¿çšãããèšèšãã¿ãŒã³ã§ãã ãã®ãã³ãã¬ãŒãã¯ãããµãŒãã¹ãã±ãŒã¿ãŒããšåŒã°ããäžå€®ã¬ãžã¹ããªã䜿çšããŸãããã®ã¬ãžã¹ããªã¯ãèŠæ±ã«å¿ããŠãç¹å®ã®ã¿ã¹ã¯ãå®äºããããã«å¿
èŠãªæ
å ±ïŒéåžžã¯ãªããžã§ã¯ãïŒãè¿ããŸãã
ãã®æ¬è³ªã¯äœã§ããïŒ äŸåé¢ä¿ãååŸããããã«ãã¯ã©ã¹ã«ã¯ã³ã³ã¹ãã©ã¯ã¿ã§ããã¡ã¯ããªããæž¡ãããããããååŸãããã®ãéžæãããŸãã
ãã®å Žåãã¯ã©ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
class Forge { func makeArmor() -> Armor { let armor = Armor(forge: self) return armor } func makeBoots() -> Boots { return Boots() } func makePants() -> Pants { return Pants() } }
class Knight { private let forge: Forge private var armor: Armor? init(forge: Forge) { self.forge = forge configure() } private func configure() { armor = forge.makeArmor() } }
class Armor { private let forge: Forge private var boots: Boots? private var pants: Pants? init(forge: Forge) { self.forge = forge configure() } private func configure() { boots = forge.makeBoots() pants = forge.makePants() } }
let forge = Forge() let knight = Knight(forge: forge)
å人çã«ããã®ã¢ãããŒãã¯äºéã®æèŠãåŒãèµ·ãããŸãã äžæ¹ã§ã¯ãçæããžãã¯ã¯ãå·¥å Žãã«ãããä»æ¹ã§ã¯ãäŸåé¢ä¿ãååŸããããã»ã¹ã¯å€å°æ··ä¹±ããŠããŸãã ããããäž»ãªæ¬ ç¹ã¯ãã¯ã©ã¹ãèŠãŠããã®äŸåé¢ä¿ãæ確ã«æ±ºå®ããããšãäžå¯èœã§ããããšã§ãã 圌ã¯ãå·¥å Žãããäœã§ãåŸãããšãã§ããŸã;å
žåçãªéçºã®ééãã¯ãã¢ããªã±ãŒã·ã§ã³å
šäœã«å¯ŸããŠãã®ãããªãå·¥å Žããäœæããããšã§ãã åæã«ããå·¥å Žãã¯ãžã£ã³ã¯ã®å·šå€§ãªãã³ãã«å€ããã圌ããæ¬åœã«å¿
èŠãšããªããã®ã®äžã«å
¥ãããšããèªæãåŒãèµ·ãããŸãã ã¯ã©ã¹ã¯é£çµ¡ãå¶éã倱ããŸãã
ç§ãã¡ã®éšå£«ã«ã¯ãå¿
èŠãªé§ãæã«å
¥ããããšãã§ããå®ç®±ãæäŸããããšæ³åã§ããŸãããä»å±ç©ã§ã¯èª°ãäžå¿
èŠãªå®ç³ã®åéãæ¢ããããšã¯ã§ããŸããã
ãã®ããããã®ãã¿ãŒã³ã¯åæªã®å¢çãè¶ããŠåãã¿ãŒã³ã«ãªããŸããã DIãšSLãéžæã§ããå Žåã¯ãåžžã«DIãéžæããŠãã ããã
DI
ã¯ã©ã¹ã«äŸåé¢ä¿ãæäŸãã2çªç®ã®æ¹æ³ã¯DIã§ãã ããã¯çŸåšæãäžè¬çãªãã¿ãŒã³ã§ãã ããã¯éåžžã«äººæ°ããããããã¯ãšã³ãã®äžçã§ã¯ããã¹ãŠã®éåžžã®ãã¬ãŒã ã¯ãŒã¯ãããã«ãµããŒãããŠããŸãã æ®å¿µãªãããç§ãã¡ã¯ããã»ã©å¹žéã§ã¯ãããŸããã§ããã
ãã®ãã¿ãŒã³ã®æ¬è³ªã¯ãäŸåé¢ä¿ãå€éšããã¯ã©ã¹ã«åã蟌ãŸããäŸåé¢ä¿ã°ã©ããDIã³ã³ãããŒå
ã«æ§ç¯ãããããšã§ããDIã³ã³ãããŒã¯ããã¡ã¯ããªãŒããŸãã¯ããã¡ã¯ããªãŒãã®ã»ããã§ãã
åæã«ã¯ã©ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
class Armor { var boots: Boots? var pants: Pants? } class Knight { var armor: Armor? } class Forge { func makeArmor() -> Armor { let armor = Armor() armor.boots = makeBoots() armor.pants = makePants() return armor } func makeBoots() -> Boots { return Boots() } func makePants() -> Pants { return Pants() } }
class Garrison { lazy var forge: Forge = { return Forge() }() func makeKnight() -> Knight { let knight = Knight() knight.armor = forge.makeArmor() return knight } }
let garrison = Garrison() let knight = garrison.makeKnight()
ãã®å Žåãã¯ã©ã¹ã¯ãããã«èŠããŸãããçæããžãã¯ã¯å®å
šã«æ¬ ããŠããŸãã ã¢ã»ã³ããªå
šäœã®è²¬ä»»ã¯ã Garrison
ãšForge
ãšãã2ã€ã®ãå·¥å ŽããåŒãåããŸããã å¿
èŠã«å¿ããŠãã¯ã©ã¹ã®æé·ãé²ãããã«ããããã®ãå·¥å Žãã®æ°ãå¢ããããšãã§ããŸãã ããããçš®é¡ã®é¢é£ãªããžã§ã¯ããäœæãããå·¥å Žããäœæããããšããå§ãããŸãã ããšãã°ããã®ãå·¥å Žãã¯ãµãŒãã¹ãç¹å®ã®ãŠãŒã¶ãŒã¹ããŒãªãŒã®ã³ã³ãããŒã©ãŒãäœæã§ããŸãã
åæã«ãç§ãã¡ã®éšå£«ã¯ã€ãã«èªåã®å°äœã«ãµãããããªãããšãããçµããåŸè
ã¯åŒŸè¬ãæ
åœããéšå£«ã¯æŠããšç女ã«éäžããããšãã§ããŸãã
ããã¯å®äºããå¯èœæ§ããããŸãããDIã®ããã€ãã®åŽé¢ãšçŸåšå©çšå¯èœãªãã¬ãŒã ã¯ãŒã¯ã«ã€ããŠè©±ã䟡å€ããããŸãã
DIã¿ã€ã
åæåã€ã³ãžã§ã¯ã¿ãŒ-ã³ã³ã¹ãã©ã¯ã¿ãŒã«ããäŸåæ§ã€ã³ãžã§ã¯ã·ã§ã³ã ãã®ã¢ãããŒãã¯ãã¯ã©ã¹ãäŸåé¢ä¿ãªãã§ã¯ååšã§ããªãå Žåã«äœ¿çšãããŸãããååšããªãå Žåã§ããã¯ã©ã¹ã³ã³ãã©ã¯ããããæ確ã«å®çŸ©ããããã«äœ¿çšã§ããŸãã ãã¹ãŠã®äŸåé¢ä¿ãã³ã³ã¹ãã©ã¯ã¿ãŒåŒæ°ãšããŠå®£èšãããŠããå Žåããããã®å®çŸ©ã¯ç°¡åã§ãã ãããã倢äžã«ãªããªãã§ãã ãããã¯ã©ã¹ã«10åã®äŸåé¢ä¿ãããå Žåã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã§ããããæž¡ããªãããšããå§ãããŸãïŒãŸãã¯ãã¯ã©ã¹ã«éåžžã«å€ãã®äŸåé¢ä¿ãããçç±ãèŠã€ããŠãã ããïŒã
class Armor { let boots: Boots let pants: Pants init(boots: Boots, pants: Pants) { self.boots = boots self.pants = pants } } class Forge { func makeArmor() -> Armor { let boots = makeBoots() let pants = makePants() let armor = Armor(boots: boots, pants: pants) return armor } func makeBoots() -> Boots { return Boots() } func makePants() -> Pants { return Pants() } }
ããããã£æ³šå
¥-ããããã£ãä»ããäŸåæ§æ³šå
¥ã ãã®ã¡ãœããã¯ãã¯ã©ã¹ã«ãªãã·ã§ã³ã®äŸåé¢ä¿ããããããããªããŠãå®è¡ã§ããå ŽåããŸãã¯äŸåé¢ä¿ããªããžã§ã¯ãã®åæå段éã ãã§ãªãå€æŽã§ããå Žåã«äœ¿çšãããŸãã
class Armor { var boots: Boots? var pants: Pants? } class Forge { func makeArmor() -> Armor { let armor = Armor() armor.boots = makeBoots() armor.pants = makePants() return armor } func makeBoots() -> Boots { return Boots() } func makePants() -> Pants { return Pants() } }
ã¡ãœãã泚å
¥-ã¡ãœãããä»ããäŸåæ§æ³šå
¥ã ãã®ã¡ãœããã¯ãããããã£ã€ã³ãžã§ã¯ã·ã§ã³ã«éåžžã«äŒŒãŠããŸãããã¢ã¯ã·ã§ã³ã®å®è¡æã«ã®ã¿æéäŸåé¢ä¿ãå®è£
ããããäŸåé¢ä¿ã®å®è£
ãã¯ã©ã¹ããžãã¯ãšããå¯æ¥ã«é¢é£ä»ããããã«äœ¿çšã§ããŸãã
class Knight { private var armor: Armor? func winTournament(armor: Armor) { self.armor = armor defeatEnemy() seducePrincess() self.armor = nil } func defeatEnemy() {} func seducePrincess() {} } class Garrison { lazy var forge: Forge = { return Forge() }() func makeKnight() -> Knight { let knight = Knight() return knight } } let garrison = Garrison() let knight = garrison.makeKnight() let armor = garrison.forge.makeArmor() knight.winTournament(armor: armor)
ç§ã®èŠ³å¯ã«ãããšãæãäžè¬çãªã¿ã€ãã¯åæåã€ã³ãžã§ã¯ã·ã§ã³ãšããããã£ã€ã³ãžã§ã¯ã·ã§ã³ã§ãããããŸãäžè¬çã§ã¯ãªãã¡ãœããã€ã³ãžã§ã¯ã·ã§ã³ã§ãã ãŸãã1ã€ã®ã¿ã€ããéžæããå
žåçãªã±ãŒã¹ã«ã€ããŠèª¬æããŸããããSwiftã¯éåžžã«æè»ãªèšèªã§ãããã¿ã€ããéžæããããã®ãªãã·ã§ã³ãè±å¯ã§ããããšãå¿ããŠã¯ãªããŸããã ãã®ãããããšãã°ããªãã·ã§ã³ã®äŸåé¢ä¿ãããå Žåã§ãããªãã·ã§ã³ã®åŒæ°ãšããã©ã«ãã§nilã䜿çšããŠã³ã³ã¹ãã©ã¯ã¿ãŒãå®è£
ã§ããŸãã ãã®å Žåãããããã£ã€ã³ãžã§ã¯ã·ã§ã³ã®ä»£ããã«åæåã€ã³ãžã§ã¯ã·ã§ã³ã䜿çšã§ããŸãã ãããã«ãããããã¯ããªãã®ã³ãŒããæ¹åãŸãã¯äœäžããã劥åã§ãããéžæã¯ããªã次第ã§ãã
ãã£ãã
äžèšã®äŸã®ããã«ãIoCãç°¡åã«äœ¿çšããããšèªäœãè¯ãææããããããŸãããããã«é²ãã§ãSOLIDã®DIPååãžã®æºæ ãéæããããšãã§ããŸãã ãããè¡ãã«ã¯ããããã³ã«ãšã®äŸåé¢ä¿ãéããããããã³ã«ãã®èåŸã«ããå®è£
ãæ£ç¢ºã«äœã§ãããããå·¥å Žãã ããç¥ããŸãã
class Knight { var armor: AbstractArmor? } class Forge { func makeArmor() -> AbstractArmor { let armor = Armor() armor.boots = makeBoots() armor.pants = makePants() return armor } func makeBoots() -> Boots { return Boots() } func makePants() -> Pants { return Pants() } }
ãã®å ŽåãäºçŽã®å®è£
ã代æ¿åã«ç°¡åã«çœ®ãæããããšãã§ããŸãã
SOLIDã¯ãã®èšäºã®ç¯å²ãè¶
ããŠããŸããããããäœã§ãããããããªãå Žåã¯ããã®äžé£ã®ååãç解ããããšããå§ãããŸãã è¯ãå
¥éèšäºããå§ããŠã ãã®æ¬ã®é¢é£ããç« ãèªã¿ç¶ããŠãã ãã ã
ã¹ã³ãŒã
ãªããžã§ã¯ãã®ã¹ã³ãŒãã管çããããšèªäœã¯IoCã³ã³ã»ããã®äžéšã§ã¯ãªãããããå®è£
ã®è©³çŽ°ã§ãããããã§ãã·ã³ã°ã«ããŒã³ãæŸæ£ããäžè¬çãªäŸåé¢ä¿ãæã€ä»ã®åé¡ã解決ã§ããéåžžã«åŒ·åãªã¡ã«ããºã ã§ãã ã¹ã³ãŒãã¯ãããã¡ã¯ããªãå
ã§äœæãããäŸåé¢ä¿ãåç¶ããæéã決å®ããŸããäŸåé¢ä¿ã¯ãæ¯åäœæãããããæåã®äœæåŸã«ä¿åãããåç
§ã«ãã£ãŠåã«æž¡ãããŸãã
ã¹ã³ãŒãã¯ãã¿ãŒã³ã«èšè¿°ãããŠããªãããããããããé©åãšæãããããã«å®è£
ããååãä»ããŸãã æãäžè¬çã«äœ¿çšããã2ã€ã®ã¿ã€ããèŠãŠãããŸãã
æšæºã¹ã³ãŒãã¯ãäžèšã®ãã¹ãŠã®äŸã§å®è£
ããåäœã§ãã ããã¡ã¯ããªãã¯ãªããžã§ã¯ããäœæãããããæž¡ãããã®ååšãå¿ããŸãã ãã¡ã¯ããªã¡ãœãããå床åŒã³åºããããšãæ°ãããªããžã§ã¯ããäœæãããŸãã
ã³ã³ããã®ã¹ã³ãŒãã¯ãã·ã³ã°ã«ãã³ã«äŒŒãåäœã§ãã ãã¡ã¯ããªã¡ãœãããæåã«åŒã³åºããããšãæ°ãããªããžã§ã¯ããäœæãããããã¡ã¯ããªãã¯ãã®åç
§ãä¿åãããã¡ã¯ããªã¡ãœããã®çµæãšããŠãããè¿ããŸããä»ã®ãã¹ãŠã®ã¡ãœããåŒã³åºãã§ã¯ãæ°ãããªããžã§ã¯ãã¯äœæãããŸããããæåã®ãªããžã§ã¯ããžã®åç
§ãè¿ãããŸãã
class Forge { private var armor: AbstractArmor? func makeArmor() -> AbstractArmor {
ã芧ã®ãšãããäžèšã®äŸã§ã¯ãé§ã¯äžåºŠã ãäœæãããä»ã®ãã¹ãŠã®å Žåã§ã¯ã以åã«äœæãããã€ã³ã¹ã¿ã³ã¹ãè¿ãããŸãã ã·ã³ã°ã«ãã³ãšåæ§ã«ãã°ããŒãã«ã¹ã³ãŒããªãã§åžžã«åãã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ã䜿çšããŸãã
é·æãšçæ
ããã°ã©ãã³ã°ã®ä»ã®ååãšåæ§ã«ãIoCã¯ç¹å¹è¬ã§ã¯ãªãã次ã®ãããªå©ç¹ããããŸãã
- ã¯ã©ã¹ã®åé床ãæžãããŸãã
- ã¯ã©ã¹ãåå©çšããæ¹ãç°¡åã§ãã
- å°è±¡çãªããžãã¯ãåé€ããããããããã³ã³ãã¯ããªã¯ã©ã¹ã
- çæããžãã¯ãã«ãã»ã«åãããªãã¡ã¯ã¿ãªã³ã°ã容æã«ããŸãã
- å®è£
ãé ããŸãã
- å®è£
ã®çœ®ãæããç°¡çŽ åããŸãã
- ãã¹ããç°¡çŽ åïŒãå·¥å Žãã眮ãæãããšãäŸåé¢ä¿ãmokamiã«çœ®ãæããããšãã§ããŸãã
- ã·ã³ã°ã«ãã³ã䜿çšããã«ãã¢ããªã±ãŒã·ã§ã³å
ã®ãªããžã§ã¯ããææ¢ãã§ããŸãã
ãããŠãçæïŒ
- æœè±¡åã®èåŸã«å®è£
ãé ããšãã«ã¯ã©ã¹ã®æ°ãå¢ãããŸãã
- ãããžã§ã¯ãã«æ²¡é ããæéã延é·ããŸãã
- ç°¡åã«ãªãŒããŒãšã³ãžãã¢ãªã³ã°ã«ã€ãªããå¯èœæ§ããããŸãã
ç§ã®æèŠã§ã¯ãã¡ã€ã³ã®å¯äžã®ãã€ãã¹ã¯ãDIPã®ååãå³å¯ã«å®ããããšããæãåã£ã欲æã®çµæãšããŠéå°ã«èšèšãããŠãããšããããšã§ãã , , , .
, , . , ? , ? ? , ?
ãŸãšãããš
, IoC , , . iOS-, , android- DI, dagger, . , , spring . php-, , , Laravel DI . iOS, , , , . Objective-C , swift.
, . , IoC â , , , , DI. IoC , DI SL, «», . «» DI .