ãã®èšäºã¯ãããã€ãã®ã¿ã¹ã¯ã«äŸ¿å©ã§ã·ã³ãã«ãªã€ã³ã¿ãŒã»ããã¡ã«ããºã ãå¿
èŠã§ãã£ããšããäºå®ããçãŸããŸããã å®è¡æã«ILã³ãŒãã®åçãªåã¯ã©ã¹ã®å®è£
ãå¿
èŠãšããã€ã³ã¿ãŒã»ãã¿ãŒïŒCasle.netãSpring.netãLinFuãªã©ïŒãéåžžã«å€ããããã€ã³ã¿ãŒã»ãããããã¯ã©ã¹ã«ã»ãšãã©åžžã«åãå¶éããããããŸããéçãéã·ãŒã«ãã¡ãœããããã³ããããã£ã¯ä»®æ³ãªã©ã§ããå¿
èŠããããŸã...
ä»ã®ååã¡ã«ããºã ã§ã¯ãã¢ã»ã³ããªããã»ã¹ã®å€æŽãŸãã¯ã©ã€ã»ã³ã¹ã®è³Œå
¥ãå¿
èŠã§ããã ç§ã¯ã©ã¡ããäžæ¹ãè²·ãäœè£ããããŸããã§ãã...
ã¯ããã«
AOP-ã¢ã¹ãã¯ãæåããã°ã©ãã³ã°ã 誰ããOPã®æå³ã«ç²ŸéããŠãããšæãã®ã§ã
ã¢ã¹ãã¯ããšã¯äœããç解ããå¿
èŠããããŸãã åŸã®èšäºã§ããã«ã€ããŠå¿é
ããå¿
èŠã¯ãããŸããã
ãã®èšäºã¯åå¿è
ã¬ãã«ã§æžãããšæããŸãã ããã«èªãããã®å¯äžã®èŠä»¶ã¯ããªããžã§ã¯ãæåããã°ã©ãã³ã°ã®æŠå¿µã®ç¥èã§ãã
æŠå¿µãç解ããããšã§ãå®è£
ãããããç解ã§ããããã«æããŸãã ããããéå±ãããç²ãããããå Žåã§ãå®è£
ã®éšåãèŠãããããã®èšäºãéåžžã«å€§ããããšãç解ããŠããŸãã ãã€ã§ãçè«ã«æ»ãããšãã§ããŸãã
çµéšè±å¯ãªéçºè
ãèªãã§ãã ããïŒ
ãã§ã«AOPã«ç²ŸéããŠããå Žåã¯ãé¢ããªãã§ãã ããïŒ
ããã§ç§ã«èãããŠãä»ç§ã¯ãã®èšäºã«ãããã®ãæããã«ããŸã...
ååããææ³ã«ã€ããŠèª¬æããŸãã
â¢ãã¹ãŠã®ã¯ã©ã¹ïŒã·ãŒã«ããéçãéèŠãªã¿ã€ããå«ãïŒ
â¢ã³ã³ã¹ãã©ã¯ã¿ãŒ
â¢ã¿ã€ãåæåå
â¢ã€ã³ã¹ã¿ã³ã¹ã¡ãœãããããããã£ãããã³ã€ãã³ãïŒä»®æ³ãšããŠããŒã¯ãããŠããªãå Žåã§ãïŒ
â¢éçã¡ãœãããããããã£ãããã³ã€ãã³ã
ãªãïŒ
â¢ã³ãŒããšã¢ã»ã³ããªãåæç»ããŸã
â¢ILã³ãŒããžã®åã蟌ã¿
â¢åçã«äœããäœæãã
â¢ã¿ãŒã²ããã¯ã©ã¹ã®å€æŽ
â¢ãŠã£ãŒããŒãäœããå®è£
ããå¿
èŠãããïŒããšãã°ãMarshalByRefïŒ
äžè¬çã«ã.Net 1.1ã§å®è¡ã§ããã¯ãªãŒã³ãªãããŒãžã³ãŒãã«ã€ããŠè©±ããŸãïŒäžè¬çã«ãç§ã¯å°ãLinqã䜿çšããŸãããç°¡åã«ãããåãé€ãããšãã§ããŸãïŒã
æåŸã«æ確ã«ããŸãã ãã®ææ³ã䜿çšããïŒ
â¢System.DateTime.NowãSystem.IO.FileïŒãªã©ã®æ§é ãã€ã³ã¿ãŒã»ããã§ããŸãïŒ
â¢ãã¹ãŠã®äžè¬çãªååã©ã€ãã©ãªã«å
±éããéåžžã®å¶éã¯ãããŸããã
ãŸã çåãããïŒ æ¬¡ã«èªãã§ãã ããïŒ
AOPã®åå
å
¥é
ãªããžã§ã¯ãæåããã°ã©ãã³ã°ã®åŠç¿æ¹æ³ã¯ãŸã å®å
šã§ã¯ãªããšèãã人ããããããããŸããããOOPããAOPã«åãæ¿ããŠãé·å¹Žã®ããŒããã¬ãŒãã³ã°ã§åŠç¿ãããã¹ãŠã®ãã©ã¯ãã£ã¹ãæŸæ£ããã®ã¯çã«ããªã£ãŠããŸããïŒ çãã¯ç°¡åã§ããåãæ¿ããå¿
èŠã¯ãããŸããã OOPãšAOPã®éã«å¯Ÿç«ã¯ãããŸããïŒ AOPã¯ãç§ã®æèŠã§ã¯ããã®ååã誀解ãæããããªæŠå¿µã§ãã AOPã®ååãç解ããã«ã¯ãOOPã§äœ¿çšãããã¹ãŠã倱ãããšã¯ã§ããªããããã¯ã©ã¹ããªããžã§ã¯ããç¶æ¿ãããªã¢ãŒãã£ãºã ãæœè±¡åãªã©ãæäœããå¿
èŠããããŸãã
æã¯ãã€ã³ã¿ãŒããããã€ãšããŒããŒãžãæ²ç€ºæ¿ããŠãŒã¶ãŒã®ããŒãžã§æ§æãããŠãããããæ¬ãèªãã§äœããåŠã¶ã®ãæåã§ããïŒæ°äžä»£ãžã®æ³šæïŒæ¬ã¯ãããã¹ããå«ãçž«ãåãããçŽã§æ§æãããŠããŸãïŒã ãããŠããããã®æ¬ã®ã»ãšãã©ãã¹ãŠã¯ã次ã®OOPã«ãŒã«ãåžžã«æãåºãããŸããã
â¢ã«ãŒã«çªå·1ïŒããŒã¿ãšã³ãŒãã®ã«ãã»ã«åãå¿
èŠã§ã
â¢ã«ãŒã«2ïŒã«ãŒã«1ãç Žããªã
ã«ãã»ã«åã¯ãOOPã第3äžä»£èšèªïŒ3GLïŒã§ç»å Žããäž»ãªç®æšã§ããã
ãŠã£ãããïŒ
ã«ãã»ã«åã¯ãé¡äŒŒããŠãããç°ãªã2ã€ã®èŠä»¶ãšãå Žåã«ãã£ãŠã¯ãããã®çµã¿åããããµããŒãããããã«äœ¿çšãããŸãã
â¢ãªããžã§ã¯ãã®äžéšã®ã³ã³ããŒãã³ããžã®ã¢ã¯ã»ã¹ãå¶éããŸãã
â¢ããŒã¿ãããã®ããŒã¿ã§æ©èœããã¡ãœããïŒãŸãã¯ä»ã®æ©èœïŒãšçµã¿åãããããšã容æã«ããèšèªæ§æã
äžè¬ã«ãAOPã¯ããã®ããŒã¿ãªãã§ã«ãã»ã«åãããããŒã¿ãæäœããã¡ãœããïŒãŸãã¯ãã®ä»ã®é¢æ°ïŒã®çµ±åãä¿é²ããããã«ãèšèªæ§é ãå¿
èŠã«ãªãå Žåããããšäž»åŒµããŠããŸãã
ãã£ããããŸãããïŒ å®éãçè«ããå¿
èŠãªã®ã¯ããã ãã§ãã ãããïŒ
ããã§ã¯ã次ã®2ã€ã®æ°ããªåé¡ã«é²ã¿ãŸãããã
â¢ãã€ãæã
ãã§ããïŒ
â¢ãªããããå¿
èŠãªã®ã§ããïŒ
AOPã®å©ç¹ã«ã€ããŠ...ããã€ãã®ã·ããªãª
ã·ããªãªA
ããªãã¯éè¡ã®éçºè
ã§ãã éè¡ã«ã¯çŽ æŽãããã·ã¹ãã ããããŸãã ããžãã¹ã¯å®å®ããŠããŸãã æ¿åºã¯ãéè¡ã«éææ§ãé«ããããšãèŠæ±ããæ³ä»€ãçºè¡ããŠããŸãã éè¡ãžã®ããŸãã¯éè¡ããã®è³éã®ç§»åãããå Žåããã®ã¢ã¯ã·ã§ã³ãèšé²ããå¿
èŠããããŸãã ãŸããæ¿åºã§ã¯ãããã¯éææ§ã«åããæåã®äžæ©ã«éãããããã«å€ãã®ããšããããšåœŒãã¯èšããŸãã
ã·ããªãªb
Webã¢ããªã±ãŒã·ã§ã³ããã¹ã¿ãŒããŒã ã«çºè¡ãããŸããã ãã¹ãŠã®æ©èœãã¹ãã«åæ Œããã¢ããªã±ãŒã·ã§ã³ã¯è² è·ãã¹ããäžæããŸããã ãµãŒããŒäžã§500ããªç§ãè¶
ããŠããŒãžãåŠçã§ããªããšããéæ©èœèŠä»¶ããããŸãã åæåŸãçµæããã£ãã·ã¥ããããšã§åé¿ã§ããå€æ°ã®ããŒã¿ããŒã¹ã¯ãšãªãèŠã€ãããŸããã
ã·ããªãªB
200幎以äžã®ã¯ã©ã¹ãå«ãçæ³çãªã©ã€ãã©ãªã§2幎éãã¡ã€ã³ã¢ãã«ãæ§ç¯ããŠããŸããã åŸã§ãã¢ããªã±ãŒã·ã§ã³çšã«æ°ããããã³ããšã³ããäœæãããŠããããã¹ãŠã®ãªããžã§ã¯ããUIã«é¢é£ä»ããå¿
èŠãããããšãããããŸãã ãã ããåé¡ã解決ããã«ã¯ããã¹ãŠã®ã¯ã©ã¹ãINotifyPropertyChangedãå®è£
ããå¿
èŠããããŸãã
äžèšã®äŸã¯ãAOPãæãã«ãªãå Žæã瀺ããŠããŸãã ãããã®ã·ããªãªã¯ãã¹ãŠã次ã®ç¹ã§é¡äŒŒããŠããŸãã
暪æçé¢å¿äº
ããšãã©ããããã¯ãã€ã§ããïŒ
äžéšã®ã¯ã©ã¹ïŒéè¡ã·ã¹ãã ãããŒã¿ã¢ã¯ã»ã¹ãµãŒãã¹ããã¡ã€ã³ã¢ãã«ïŒã¯ãäžè¬ã«ã圌ãã®ããžãã¹ãã§ã¯ãªãæ©èœãååŸããå¿
èŠããããŸãã
â¢éè¡ã·ã¹ãã ã®ããžãã¹ã¯ãééã§ãã äŒæ¡äœæ¥ã«ã¯æ¿åºãå¿
èŠã§ãã
â¢ããŒã¿ãåä¿¡ããã«ã¯ãããŒã¿ã¢ã¯ã»ã¹ãµãŒãã¹ãå¿
èŠã§ãã ããŒã¿ãã£ãã·ã³ã°ã¯éæ©èœèŠä»¶ã§ãã
â¢ãã¡ã€ã³ã¢ãã«ã¯ã©ã¹ã¯ãäŒç€Ÿã®ããžãã¹ããžãã¯ãå®è£
ããŸãã ããããã£ã®å€æŽã«é¢ããUIã®éç¥ã¯ãUIã§ã®ã¿å¿
èŠã§ãã
äžè¬ã«ããããã®ã¯ã©ã¹ã«åºæã§ã¯ãªãåé¡ã解決ããããã«ãããŸããŸãªã¯ã©ã¹ã®ã³ãŒããèšè¿°ããå¿
èŠãããç¶æ³ã«ã€ããŠè©±ããŸãã AOPã®æ¹èšã§è©±ã-å®è£
ãããã¢ã¯ã·ã§ã³ãå¿
èŠã§ãã
å®è£
ãããŠããã¢ã¯ã·ã§ã³ãç解ããããšãAOPã®éµã§ãã å®è£
ãããã¢ã¯ã·ã§ã³ã¯ãããŸãã-AOPã®å¿
èŠã¯ãããŸããã
ãªããããå¿
èŠãªã®ã§ããïŒ
ã·ããªãªBã詳ããèŠãŠã¿ãŸãããã
åé¡ã¯ãããšãã°ãåã¯ã©ã¹ã«å¹³å5ã€ã®ããããã£ãããããšã§ãã 200以äžã®ã¯ã©ã¹ãããããã次ã®ãããªã³ãŒããå€æããã«ã¯ã1000以äžã®ãã³ãã¬ãŒãã³ãŒããå®è£
ïŒã³ããŒã¢ã³ãããŒã¹ãïŒããå¿
èŠããããŸãã
public class Customer { public string Name { get; set; } }
次ã®ãããªãã®ã§ïŒ
public class Customer : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string _Name; public string Name { get { return _Name; } set { if (value != _Name) { _Name = value; SignalPropertyChanged("Name"); } } } void SignalPropertyChanged(string propertyName) { var pcEvent = this.PropertyChanged; if (pcEvent != null) pcEvent(this, new PropertyChangedEventArgs(propertyName)); } }
ãã㌠ãããŠãããã¯ãã äžã€ã®è²¡ç£ã§ãïŒ ãšããã§ãããªãã¯ææ°ã§ããïŒ ã€ã³ã¿ãŒã³ã¯æ°æ¥åã«èŸããŸãã
ããã®ããŒã¿ãªãã§ã«ãã»ã«åãããããŒã¿ãæäœããã¡ãœããïŒãŸãã¯ä»ã®é¢æ°ïŒã®çµã¿åããããå¿
èŠã§ãã ã€ãŸããCustomeråã®ãã¡ã€ã³ã¢ãã«ã®ã¯ã©ã¹ãå€æŽããã«ããŸãã¯æå°éã®å€æŽã§INotifyPropertyChangedã¢ã¯ã·ã§ã³ã®å®è£
ãå®è£
ããŸãã
ãããå®è£
ã§ããå Žåã次ã®ããã«ãªããŸãã
â¢ã¢ã¯ã·ã§ã³ã®æ確ãªåé¢
â¢ã³ãŒãã®ç¹°ãè¿ããé¿ããéçºãã¹ããŒãã¢ãããã
â¢å€§éã®å®åã³ãŒãã®äžã§ãã¡ã€ã³ã¯ã©ã¹ãé ããªãããã«ããŸãã
ãã ããããããããã¹ãŠè¡ãæ¹æ³ã¯ïŒ
çè«çãªçã
ããã€ãã®ã¯ã©ã¹ã§å®è¡ããå¿
èŠã®ããã¢ã¯ã·ã§ã³ãå®è£
ããŠããŸãïŒä»¥éãç®æšãšåŒã³ãŸãïŒã å®è£
ïŒãã®ã³ã°ããã£ãã·ã¥ããŸãã¯ä»ã®äœããå®è£
ããã³ãŒãïŒã¯ãAOPã¢ã¯ã·ã§ã³ãšåŒã°ããŸãã
次ã«ãå¿
èŠãªå Žæã«ã¢ã¯ã·ã§ã³ãè¿œå ïŒåã蟌ã¿ãåã蟌ã¿ãåèªã®éžæïŒããå¿
èŠããããŸãïŒããã¯éèŠã§ããã¢ã¯ã·ã§ã³ã¯å®è£
ãããã¢ã¯ã·ã§ã³ã®å®è£
ã§ãïŒã ãããŠãã¢ã¯ã·ã§ã³ã®å®è£
ã®ç®æšã®æ¬¡ã®å Žæã®ãããããéžæã§ããã¯ãã§ãã
â¢éçåæåå
â¢ã³ã³ã¹ãã©ã¯ã¿ãŒ
â¢éçããããã£ã®èªã¿åããšæžã蟌ã¿
â¢ã€ã³ã¹ã¿ã³ã¹ããããã£ã®èªã¿åããšæžã蟌ã¿
â¢éçã¡ãœãã
â¢ã€ã³ã¹ã¿ã³ã¹ã¡ãœãã
â¢ãã¹ãã©ã¯ã¿
çæ³çãªAOPã§ã¯ãã¿ãŒã²ããã³ãŒãã®ä»»æã®è¡ã«ã¢ã¯ã·ã§ã³ãå®è£
ã§ããå¿
èŠããããŸãã
ãã°ãããã§ãããã¢ã¯ã·ã§ã³ãã¢ã¿ããããå¿
èŠãããå Žåãã¿ãŒã²ããã«ã€ã³ã¿ãŒã»ãã¿ãŒãå¿
èŠã§ããïŒ ã¯ããCEPïŒ
AOPã§ã¯ãã€ã³ã¿ãŒã»ãã¿ãŒã®èª¬æïŒã¢ã¯ã·ã§ã³ãå®è¡ãããå ŽæïŒã®ååã¯pointcutã§ãã ãããŠãã³ãŒããå®éã«ãã€ã³ãããå ŽæïŒæ¥ç¶ãã€ã³ãã
ããã§ãã ãã¶ãããã§ã¯ãããŸãã...ããã«ã¡ãã£ãšããæ¬äŒŒã³ãŒãããããŸãã
ãã®ãããªã¡ã«ããºã ããã®ãŸãŸCïŒã§äœ¿çšããã®ã¯ã¯ãŒã«ã§ããããïŒ
ããã«ããã€ãã®æŠå¿µ
å®è£
ã«ç§»ãåã«ãããã«ããã€ãã®æŠå¿µã瀺ããŸã...
ã¢ã¹ãã¯ããšã¯äœã§ããïŒ
ããã¯ãã¢ã¯ã·ã§ã³ãã¹ã©ã€ã¹ãããã³æ¥ç¶ãã€ã³ãã®çµã¿åããã§ãã
å°ãèããŠã¿ãŠãã ããããã¹ãŠãé©åã«æ©èœããããšãé¡ã£ãŠããŸããã¢ããªã±ãŒã·ã§ã³ã®æå®ãããå ŽæïŒã¹ã©ã€ã¹ïŒã«ãå®è¡ïŒæ¥ç¶ãã€ã³ãïŒã®ããã®ãã®ã³ã°ã¡ãœãããç»é²ãããã®ã³ã°ã¡ã«ããºã ïŒã¢ã¯ã·ã§ã³ïŒããããŸãã ãããã¯ãã¹ãŠãç§ã®ã¢ããªã±ãŒã·ã§ã³ã®åŽé¢ã§ãã
ããããã¡ãã£ãšåŸ
ã£ãŠãã ãã...å®è£
åŸãã¢ã¯ã·ã§ã³ã¯äœããã¹ãã§ãããäœãã§ããŸããïŒ
ã¢ã¯ã·ã§ã³ã¯2ã€ã®ã«ããŽãªã«åé¡ãããŸãã
å¯äœçšã
å¯äœçšã¯ãã¹ã©ã€ã¹å
ã®ã³ãŒãã®ã¢ã¯ã·ã§ã³ãå€æŽããªãã¢ã¯ã·ã§ã³ã§ãã å¯äœçšãšããŠãå®è¡ããã³ãã³ãã®çš®é¡ãè¿œå ããã ãã§ãã
ãã®ã³ã°ã¢ã¯ã·ã§ã³ã¯ãå¯äœçšã®è¯ãäŸã§ãã ç°å¢ãã¿ãŒã²ããã¡ãœããïŒBank.WithdrawïŒint AmountïŒãªã©ïŒãå®è¡ãããšãLoggingConcern.LogWithdrawïŒint AmountïŒã¡ãœãããå®è¡ãããBank.WithdrawïŒint AmountïŒã¡ãœããã®å®è¡ãç¶ç¶ãããŸãã
ãã³ã
ãã³ã-ã¡ãœããã®å
¥å/åºåãå€æŽã§ããã¢ã¯ã·ã§ã³ã
ã¢ã¯ã·ã§ã³ãã£ãã·ã³ã°ã¯çŽ æŽãããäŸã§ãã ã¿ãŒã²ããã¡ãœãããå®è¡ããããšïŒããšãã°ãCustomerService.GetByIdïŒint IdïŒïŒãCachingConcern.TryGetCustomerByIdïŒint IdïŒã¡ãœãããå®è¡ããããã£ãã·ã¥ã§èŠã€ãã£ãå€ãè¿ãããååšããªãå Žåã¯å®è¡ãç¶ç¶ããŸãã
ãã³ãã¯æ¬¡ã®ãšããã§ãã
â¢ã¿ãŒã²ããã»ã¯ã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒãšãå¿
èŠã«å¿ããŠå€æŽããæ©èœã確èªããŸãã
â¢ã¿ãŒã²ããã¡ãœããã®å®è¡ããã£ã³ã»ã«ããå¥ã®å®è£
ã«çœ®ãæããŸã
â¢ã¿ãŒã²ããã¡ãœããã®æ»ãå€ã確èªããå€æŽãŸãã¯çœ®æãã
ãŸã èªãã§ããŸããïŒ ãã©ããŒïŒ Parce que vous le valez bien ...
ããã§ãAOPã®æŠå¿µãšæŠå¿µã¯çµããã§ãã CïŒã§åœŒããã£ãšããç¥ããŸãããã
ç§ãã¡ã®å®è£
ã³ãŒãu je tue le chienãèŠããŠãã ããïŒ
ã¢ã¯ã·ã§ã³
ã¢ã¯ã·ã§ã³ã¯ããã®ããžãã¯ãå®è£
ããå¿
èŠããããŸããããã¯ç®æšã®ã¿ã€ãã§ãã
åé¡ãããŸããïŒ
public interface IConcern<T> { T This { get; }
ã¹ã©ã€ã¹ïŒãã€ã³ãã«ããïŒ
ã³ãŒãã®åè¡ã®ã¹ã©ã€ã¹ãååŸããç°¡åãªæ¹æ³ã¯ãããŸããã ãããã1ã€ãã€ååŸããããšãã§ããSystem.Reflection.MethodBaseã¯ã©ã¹ã䜿çšãããšéåžžã«ç°¡åã§ãã MSDNã¯ããã«ã€ããŠåé·ã§ã¯ãããŸããïŒã¡ãœãããšã³ã³ã¹ãã©ã¯ã¿ãŒã«é¢ããæ
å ±ãæäŸããŸãã
ç§ãã¡ã®éã§ã¯ãMethodBaseã䜿çšããŠã¹ã©ã€ã¹ãªã³ã¯ãååŸããããšãããã®ã¿ã¹ã¯ã§æã匷åãªããŒã«ã§ãã
.Netã§å®£èšããã»ãšãã©ãã¹ãŠãæçµçã«ã¡ãœããã«ãªããããã³ã³ã¹ãã©ã¯ã¿ãã¡ãœãããããããã£ãããã³ã€ãã³ãã®ã¹ã©ã€ãµãŒã«ã¢ã¯ã»ã¹ã§ããŸã...
èªåã§èŠãŠãã ããïŒ
public class Customer { public event EventHandler<EventArgs> NameChanged; public string Name { get; private set; } public void ChangeName(string newName) { Name = newName; NameChanged(this, EventArgs.Empty); } } class Program { static void Main(string[] args) { var t = typeof(Customer);
ãžã§ã€ã³ãã€ã³ã
æ¥ç¶çšã®ã³ãŒãã®èšè¿°ã¯æ¬åœã«ç°¡åã§ãã ãã®ã³ãŒããèŠãŠãã ããïŒ
void Join(System.Reflection.MethodBase pointcutMethod, System.Reflection.MethodBase concernMethod);
ã¬ãžã¹ããªã®ãããªãã®ã«è¿œå ããããšãã§ããŸããããã¯åŸã§è¡ããŸãããããŠããã®ãããªã³ãŒããæžãå§ããããšãã§ããŸã!!!
public class Customer { public string Name { get; set;} public void DoYourOwnBusiness() { System.Diagnostics.Trace.WriteLine(Name + " "); } } public class LoggingConcern : IConcern<Customer> { public Customer This { get; set; } public void DoSomething() { System.Diagnostics.Trace.WriteLine(This.Name + " "); This.DoYourOwnBusiness(); System.Diagnostics.Trace.WriteLine(This.Name + " "); } } class Program { static void Main(string[] args)h {
æ¬äŒŒã³ãŒãããé ãã§ããïŒ ç§ã®æèŠã§ã¯ãå®éã«ã¯...
ããã§ã¯ã次ã¯äœã§ããïŒ
ãã¹ãŠããŸãšãããš...
ããã§åé¡ãšæ¥œãã¿ãåæã«å§ãŸããŸãïŒ
ããããç°¡åãªããšããå§ããŸããã
ã¬ãžã¹ããª
ã¬ãžã¹ããªã¯ãæ¥ç¶ãã€ã³ãã®èšé²ãä¿æããŸãã æ¥ç¶ãã€ã³ãã®ã·ã³ã°ã«ãã³ãªã¹ããååŸããŸãã æ¥åç¹ã¯åçŽãªæ§é ã§ãïŒ
public struct Joinpoint { internal MethodBase PointcutMethod; internal MethodBase ConcernMethod; private Joinpoint(MethodBase pointcutMethod, MethodBase concernMethod) { PointcutMethod = pointcutMethod; ConcernMethod = concernMethod; }
ç¹å¥ãªããšã¯äœããããŸãã... IEquatableãå®è£
ããå¿
èŠããããŸãããã³ãŒããçãããããã«åé€ããŸããã
ãããŠãã¬ãžã¹ããªã ãã®ã¯ã©ã¹ã¯AOPãšåŒã°ããã·ã³ã°ã«ãã³ã§ãã Registryãšããéçããããã£ãä»ããŠãäžæã®ã€ã³ã¹ã¿ã³ã¹ãžã®ã¢ã¯ã»ã¹ãæäŸããŸãã
public class AOP : List<Joinpoint> { static readonly AOP _registry; static AOP() { _registry = new AOP(); } private AOP() { } public static AOP Registry { get { return _registry; } } [MethodImpl(MethodImplOptions.Synchronized)] public void Join(MethodBase pointcutMethod, MethodBase concernMethod) { var joinPoint = Joinpoint.Create(pointcutMethod, concernMethod); if (!this.Contains(joinPoint)) this.Add(joinPoint); } }
AOPã¯ã©ã¹ã䜿çšããŠã次ã®æ§æãèšè¿°ã§ããŸãã
AOP.Registry.Join(pointcut, concernMethod);
ãã¥ãŒã¹ãã³ãåé¡ããããŸã
ããã§ãç§ãã¡ã¯äœããããå¿
èŠãããæçœã§å€§ããªåé¡ã«çŽé¢ããŠããŸãã éçºè
ããã®ããã«æžããå Žå
var customer = new Customer {Name="test"}; customer.DoYourOwnBusiness();
ãã®åŸãã¬ãžã¹ããªã«ã¢ã¯ã»ã¹ããçç±ã¯ãªããLoggingConcern.DoSomethingïŒïŒã¡ãœããã¯éå§ãããŸããã
åé¡ã¯ããã®ãããªåŒã³åºããååããç°¡åãªæ¹æ³ã.NetãæäŸããŠããªãããšã§ãã
çµã¿èŸŒã¿ã®ã¡ã«ããºã ããªããããç¬èªã«äœæããå¿
èŠããããŸãã ã¡ã«ããºã ã®æ©èœã«ãããAOPã®å®è£
ã®æ©èœã決ãŸããŸãã
ãã®èšäºã®ç®çã¯ãèãããããã¹ãŠã®ååææ³ã«ã€ããŠèª¬æããããšã§ã¯ãããŸããã ååæ¹æ³ã¯ãAOPå®è£
ã®éèŠãªéãã§ããããšã«æ³šæããŠãã ããã
SharpCraftersã®Webãµã€ãïŒPostSharpã®ææè
ïŒã¯ã2ã€ã®äž»ãªãã¯ããã¯ã«é¢ããæ確ãªæ
å ±ãæäŸããŠããŸãã
â¢ã³ã³ãã€ã«æã®åã蟌ã¿
â¢å®è¡æã®åã蟌ã¿
å®è£
-ãããã·
äžè¬çã«ãã€ã³ã¿ãŒã»ããã«ã¯3ã€ã®ãªãã·ã§ã³ãããããšã¯ç§å¯ã§ã¯ãããŸããã
â¢.netã¢ã»ã³ããªãååŸããããã®ç¬èªã®èšèªãšã³ã³ãã€ã©ãäœæããŸããã³ã³ãã€ã«æã«ãã©ãã«ã§ãäœã§ãåã蟌ãããšãã§ããŸãã
â¢å®è¡æã«ã¢ã»ã³ããªã®åäœãå€æŽãããœãªã¥ãŒã·ã§ã³ãå®è£
ããŸãã
â¢åŒã³åºããã€ã³ã¿ãŒã»ããããã¯ã©ã€ã¢ã³ããšã¿ãŒã²ãããããã·ã®éã«é
眮ããŸãã
äžçŽè
åãã®ã¡ã¢ïŒãããã¬ãŒãšãããã¡ã€ã©ãŒAPIã®äœ¿çšã¯æ¬çªç°å¢ã§ã¯å®è¡ã§ããªããããæå³çã«ãããã¬ãŒãšãããã¡ã€ã©ãŒAPIã®å¯èœæ§ãèæ
®ããŸããã
æãé«åºŠãªæ³šæäºé
ïŒRaslyn APIã§äœ¿çšãããæåãš2çªç®ã®ãªãã·ã§ã³ã®ãã€ããªãããå®è£
ã§ããŸãããç§ãç¥ã£ãŠããããã«ãããã¯ãŸã è¡ãããŠããã ãã§ãã bon entendeur ...
ããã«ãã³ãŒãã®è¡ãã«ããããå¿
èŠããªãå Žåãæåã®2ã€ã®ãªãã·ã§ã³ã¯è€éãããŸãã
3çªç®ã®ãªãã·ã§ã³ã«é²ã¿ãŸãããã ãããã·ã«é¢ãã2ã€ã®ãã¥ãŒã¹ããããŸããè¯ãç¹ãšæªãç¹ã§ãã
æªã-å®è¡äžã«ãã¿ãŒã²ãããã¬ã¹ã±ããã®ã€ã³ã¹ã¿ã³ã¹ã«çœ®ãæããå¿
èŠããããŸãã ã³ã³ã¹ãã©ã¯ã¿ãŒãã€ã³ã¿ãŒã»ããããå Žåã¯ãã¿ãŒã²ããã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã®äœæããã¡ã¯ããªãŒã«å§ä»»ããå¿
èŠããããŸã;ãã®å®è£
ã¯ã¢ã¯ã·ã§ã³ãçµ±åã§ããŸããã ã¿ãŒã²ããã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãååšããå Žåãæ瀺çã«çœ®æãèŠæ±ããå¿
èŠããããŸãã
管çã®
å転ãš
äŸåæ§æ³šå
¥ã®ãã¹ã¿ãŒã®å Žå-ããã¯ã¿ã¹ã¯ã§ããããŸããã æ®ãã«ã€ããŠã¯ãããã¯ãã¡ã¯ããªãŒã䜿çšããŠã€ã³ã¿ãŒã»ããææ³ã®ãã¹ãŠã®æ©èœãæäŸããå¿
èŠãããããšãæå³ããŸãã ã§ãå¿é
ããªãã§ããã®å·¥å Žã建ãŠãŸãã
è¯ããã¥ãŒã¹ã¯ããããã·ãå®è£
ããããã«äœãããå¿
èŠããªããšããããšã§ãã System.Runtime.Remoting.Proxies.RealProxyã¯ã©ã¹ã¯ãæé©ãªæ¹æ³ã§æ§ç¯ããŸãã
ç§ã®æèŠã§ã¯ãã¯ã©ã¹ã®ååã¯ãã®ç®çãåæ ããŠããŸããã ãã®ã¯ã©ã¹ã¯ãããã·ã§ã¯ãªããã€ã³ã¿ãŒã»ãã¿ãŒã§ãã ããã§ãã圌ã¯GetTransparentProxyïŒïŒã¡ãœãããåŒã³åºããŠãããã·ãäœæããŸããããããå®éã«åœŒããå¿
èŠãªãã®ã§ãã
ãããè¿æéã§ãã
public class Interceptor : RealProxy, IRemotingTypeInfo { object theTarget { get; set; } public Interceptor(object target) : base(typeof(MarshalByRefObject)) { theTarget = target; } public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg) { IMethodCallMessage methodMessage = (IMethodCallMessage) msg; MethodBase method = methodMessage.MethodBase; object[] arguments = methodMessage.Args; object returnValue = null;
ããã€ãã®èª¬æã ç§ãã¡ã¯å®çŸã®äžå¿ã«ç»ããŸãã...
RealProxyã¯ã©ã¹ã¯ããªã¢ãŒããªããžã§ã¯ãããã®åŒã³åºããã€ã³ã¿ãŒã»ããããã¿ãŒã²ãããæŽçããããã«èšèšãããŠããŸãã ãªã¢ãŒãã¯ãçã«ãªã¢ãŒããšããŠç解ããå¿
èŠããããŸãïŒå¥ã®ã¢ããªã±ãŒã·ã§ã³ãå¥ã®ã¢ããªã±ãŒã·ã§ã³ãã¡ã€ã³ãå¥ã®ãµãŒããŒãªã©ããã®ãªããžã§ã¯ãã 詳现ã«ã¯è§ŠããŸãããã.Netã€ã³ãã©ã¹ãã©ã¯ãã£ã§ãªã¢ãŒããªããžã§ã¯ããæŽçããã«ã¯ãåç
§ãšå€ã®2ã€ã®æ¹æ³ããããŸãã ãããã£ãŠãåé€ããããªããžã§ã¯ãã¯ãMarshalByRefãç¶æ¿ããããISerializableãå®è£
ããå Žåã«ã®ã¿æ³šæã§ããŸãã ãªã¢ãŒããªããžã§ã¯ãã®æ©èœã¯äœ¿çšããŸããããããã§ããã¿ãŒã²ããããªã¢ãŒãã³ã³ãããŒã«ããµããŒãããŠãããšèããã«ã¯RealProxyã¯ã©ã¹ãå¿
èŠã§ãã ãã®ãããtypeofïŒMarshalByRefïŒãRealProxyã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ããŸãã
RealProxyã¯ãInvokeã¡ãœããïŒSystem.Runtime.Remoting.Messaging.IMessage msgïŒã䜿çšããŠãééãããã·çµç±ã§ãã¹ãŠã®åŒã³åºããåä¿¡ããŸãã ã¡ãœããã®çœ®æã®æ¬è³ªãç解ããã®ã¯ããã§ãã äžèšã®ã³ãŒãã®ã³ã¡ã³ããåç
§ããŠãã ããã
IRemotingTypeInfoã®å®è£
ã«é¢ããŠïŒå®éã®ãªã¢ãŒãç°å¢ã§ã¯ãã¯ã©ã€ã¢ã³ãã¯ãµãŒããŒã«ãªããžã§ã¯ããèŠæ±ããŸãã ã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ã¯ãåä¿¡ãããªããžã§ã¯ãã®çš®é¡ã«ã€ããŠäœãç¥ããªãå ŽåããããŸãã ãããã£ãŠãã¯ã©ã€ã¢ã³ãã¢ããªã±ãŒã·ã§ã³ããããªãã¯ãªããžã§ã¯ãGetTransparentProxyïŒïŒãåŒã³åºããšãç°å¢ã¯è¿ããããªããžã§ã¯ãïŒééãããã·ïŒãã¢ããªã±ãŒã·ã§ã³ã³ã³ãã©ã¯ãã«æºæ ããããšãã§ããŸãã IRemotingTypeInfoãå®è£
ããããšã«ãããã©ã®ãã£ã¹ããæå¹ã§ãã©ã®ãã£ã¹ããç¡å¹ã§ããããã¯ã©ã€ã¢ã³ãç°å¢ã«ç€ºåããŸãã
ããã§äœ¿çšããŠããããªãã¯ã«é©åããŠãã ããã
public bool CanCastTo(Type fromType, object o) { return true; }
AOPã®å®è£
å
šäœã¯ãããã2ã€ã®åèªããªã¢ãŒããªããžã§ã¯ãã«æžã蟌ãããšãã§ãããšããçç±ã ãã§å¯èœã§ããtrueãè¿ããŸãã ããã¯ãGetTransparentProxyïŒïŒã«ãã£ãŠè¿ããããªããžã§ã¯ã
ããç°å¢ãã§ãã¯ãªãã§ä»»æã®ã€ã³ã¿ãŒãã§ã€ã¹ã«ãã£ã¹ãã§ããããšãæå³ã
ãŸã!!!!æ°Žææ¥ã¯ç§ãã¡ã«ããããè¡åã®å
åããäžããã ãã§ãïŒ
ãã®ã³ãŒããä¿®æ£ããŠãã©ã®ã¿ã€ãã§ãtrueãããåççãªãã®ãè¿ãããšãã§ããŸã...ãããã
ååšããªãã¡ãœããã«ãã£ãŠæäŸãããåäœãå©çš
ããæ¹æ³ããã€ã³ã¿ãŒãã§ã€ã¹å
šäœãã€ã³ã¿ãŒã»ããããæ¹æ³ãæ³åããããšãã§ããŸã...äžè¬çã«ãæ³åã®ããã®ã¹ããŒã¹ãããªããããŸã...
ããã§ãã¿ãŒã²ããã€ã³ã¹ã¿ã³ã¹ã«é©åãªã€ã³ã¿ãŒã»ããã¡ã«ããºã ãæ¢ã«ãããŸãã ããããã³ã³ã¹ãã©ã¯ã¿ãŒã®ã€ã³ã¿ãŒã»ãããšééçãªãããã·ã¯ãŸã ãããŸããã ããã¯å·¥å Žã«ãšã£ãŠã®ææŠã§ã...
å·¥å Ž
äœãèšãããšã¯ãããŸããã ãããã¯ã©ã¹ã®éã§ãã
public static class Factory { public static object Create<T>(params object[] constructorArgs) { T target;
Factoryã¯ã©ã¹ã¯åžžã«ãªããžã§ã¯ãåã®ãªããžã§ã¯ããè¿ãããšã«æ³šæããŠãã ããã ééãããã·ãTåã§ã¯ãªããSystem.Runtime.Remoting.Proxies .__ TransparentProxyåã§ãããããTåã®ãªããžã§ã¯ããè¿ãããšã¯ã§ããŸããã ããããç°å¢ããäžãããã解å床ãæãåºããŠãã ããã
è¿ããããªããžã§ã¯ãããã§ãã¯ããã«ä»»æã®ã€ã³ã¿ãŒãã§ã€ã¹ã«ãã£ã¹ãã§ããŸããã客æ§ã«é©åãªã³ãŒããæž¡ãããšãæåŸ
ããŠãAOPã¯ã©ã¹ã«Factoryã¯ã©ã¹ãé
眮ããŸãã ããã¯ã䜿çšæ³ã»ã¯ã·ã§ã³ã§ç¢ºèªã§ããŸãã
ææ°ã®å®è£
ããŒã
ãããŸã§èªãã ããããªãã¯ããŒããŒã§ãïŒ ãã©ãã·ã¢ïŒ 称è³ïŒ
ãã®èšäºãç°¡æœã§ç解ãããããã®ã«ããããã«ïŒãããŠäœãé¢çœãã®ãïŒãã¡ãœããã®ååŸãšåãæ¿ãã®å®è£
ã®è©³çŽ°ã«ã€ããŠã®éå±ãªè°è«ã¯ããŸããã ããã«ã€ããŠã¯äœãèå³æ·±ãããšã¯ãããŸããã ãããããŸã èå³ãããå Žåã¯ãã³ãŒããããŠã³ããŒãããŠç¢ºèªããŠãã ãã-å®å
šã«æ©èœããŠããŸãïŒ ã¯ã©ã¹ãšã¡ãœããã®ååã¯ããããã«ç°ãªãå ŽåããããŸãã ç§ã¯ããã䞊è¡ããŠè£å®ããŸããããããã»ã©å€§ããªå€æŽã¯ãªãã¯ãã§ãã
泚æïŒ ãããžã§ã¯ãã§ã³ãŒãã䜿çšããåã«ã paenultimusã泚ææ·±ãèªãã§ãã ãã ã ãŸããpaenultimusã®æå³ãããããªãå Žåã¯ããªã³ã¯ãã¯ãªãã¯ããŠãã ããã
䜿çšãã
ç§ã¯ãã§ã«å€ãã®ããšãæžããŸãããããŸã ããããã¹ãŠãã©ããããã瀺ããŠããŸããã ãããŠãããã§åœŒã¯çå®ã®ç¬éã§ãïŒ
ã¢ãŒã«ã€ãã«ã¯ã次ã®åŽé¢ã®å®è£
ã瀺ã5ã€ã®äŸãå«ãŸããŠããŸãã
â¢ãã¶ã€ããŒã®åå
â¢ã¡ãœãããšããããã£ã®åå
â¢ã€ãã³ãã®åå
â¢ã¿ã€ãåæåã€ã³ã¿ãŒã»ãã
â¢Interception File.ReadAllTextïŒæååãã¹ïŒ
ãããŠãããã§ã¯ã5ã€ã®ãã¡ã®2ã€ã瀺ããŸãã
ã¡ãœãããšããããã£ã®åå
ãŸãããã¡ã€ã³ã¢ãã«ãå¿
èŠã§ãã ç¹å¥ãªããšã¯äœããããŸããã
public interface IActor { string Name { get; set; } void Act(); } public class Actor : IActor { public string Name { get; set; } public void Act() { Console.WriteLine("My name is '{0}'. I am such a good actor!", Name); } }
ä»ãç§ãã¡ã¯è¡åãå¿
èŠã§ã
public class TheConcern : IConcern<Actor> { public Actor This { get; set; } public string Name { set { This.Name = value + ". Hi, " + value + " you've been hacked"; } } public void Act() { This.Act(); Console.WriteLine("You think so...!"); } }
ã¢ããªã±ãŒã·ã§ã³ãåæåããããšãæ¥ç¶ãã€ã³ãã«ã€ããŠã¬ãžã¹ããªã«éç¥ããŸã
ãããŠæåŸã«ããã¡ã¯ããªãŒã§ãªããžã§ã¯ããäœæããŸã
var actor1 = (IActor) AOP.Factory.Create<Actor>(); actor1.Name = "the Dude"; actor1.Act();
Actorã¯ã©ã¹ã®äœæããªã¯ãšã¹ãããŸããããçµæãã€ã³ã¿ãŒãã§ã€ã¹ã«æã£ãŠããããšãã§ããããšã«æ³šæããŠãã ããããããã£ãŠãIActorã«ã€ãªãããŸãã ã¯ã©ã¹ã¯ãããå®è£
ããŸãã
ããããã¹ãŠãã³ã³ãœãŒã«ã¢ããªã±ãŒã·ã§ã³ã§å®è¡ãããšã次ã®ããã«ãªããŸãã
My name is 'the Dude. Hi, the Dude you've been hacked'. I am such a good actor!
You think so...!
Interception File.ReadAllTextïŒæååãã¹ïŒ
ããã«ã¯2ã€ã®å°ããªåé¡ããããŸãã
â¢ãã¡ã€ã«ã¯ã©ã¹ã¯éçã§ã
â¢ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããŠããŸãã
ãè¯ãããèŠããŠããŸããïŒ ç°å¢ã¯ãè¿ããããããã·ã®ã¿ã€ããšã€ã³ã¿ãŒãã§ãŒã¹ããã§ãã¯ããŸããã
ãããã£ãŠãä»»æã®ã€ã³ã¿ãŒãã§ã€ã¹ãäœæã§ããŸãã ç®æšãè¡åã誰ãå®çŸããŸããã äžè¬çã«ãã€ã³ã¿ãŒãã§ã€ã¹ã¯ã³ã³ãã©ã¯ããšããŠäœ¿çšããŸãã
éçã¯ã©ã¹Fileãè£
ã£ãã€ã³ã¿ãŒãã§ã€ã¹ãäœæããŸãããã
public interface IFile { string[] ReadAllLines(string path); }
ç§ãã¡ã®è¡å
public class TheConcern { public static string[] ReadAllLines(string path) { return File.ReadAllLines(path).Select(x => x + " hacked...").ToArray(); } }
åå ãã€ã³ãç»é²
AOP.Registry.Join ( typeof(File).GetMethods().Where(x => x.Name == "ReadAllLines" && x.GetParameters().Count() == 1).First(), typeof(TheConcern).GetMethod("ReadAllLines") );
ãããŠæåŸã«ãããã°ã©ã ã®å®è¡
var path = Path.Combine(Environment.CurrentDirectory, "Examples", "data.txt"); var file = (IFile) AOP.Factory.Create(typeof(File)); foreach (string s in file.ReadAllLines(path)) Console.WriteLine(s);
ãã®äŸã§ã¯ãFactory.Createã¡ãœããã䜿çšã§ããªãããšã«æ³šæããŠãã ããã éçåã¯åŒæ°ãšããŠäœ¿çšã§ããŸããã
åç
§è³æ
ç¹å¥ãªæ³šæãªãã
â¢
Qi4jã®ãã¥ãŒããªã¢ã«â¢
RealProxyã®æ¡åŒµâ¢
åçãããã·ãã¥ãŒããªã¢ã«ïŒCastle.netïŒâ¢
LinFu.DynamicProxyïŒè»œéãããã·ãžã§ãã¬ãŒã¿ãŒâ¢
Dynamic Decoratorã䜿çšããŠã¢ã¹ãã¯ããè¿œå ããâ¢
AOPã€ã³ã¿ãŒã»ãã¿ãŒãšããŠæ©èœããCLRãããã¡ã€ã©ãŒã®å®è£
â¢
.Netã®ååâ¢
AspectF Fluent Way to Addspects to Aspects Cleaner Maintainable Code次ã¯ïŒ
AOPã®äž»ãªç®æšã§ããã¢ã¹ãã¯ããå®çŸããå®è¡ã®ããã«ç»é²ããããšãã§ããŸããã TinyAOPãèªçããŸããã ããããAOPã®åå°ã§ã®ããªãã®éã¯ãŸã çµãã£ãŠããªãã®ã§ããã£ãšæ·±ãããããšæããããããŸããã
çç±1ïŒçŸåšã®ããã«èª°ããžã£ã³ã¯ã·ã§ã³ãã€ã³ããç»é²ãããã®ã§ããïŒ ééããªãç§ã®ããã§ã¯ãããŸããïŒ å°ãã®åæãããå®çšçã«è¡ãããšãã§ããå®éã®AOPã©ã€ãã©ãªã«äŒŒãŠããŸãã AOPã¯ãé çãåŒãèµ·ããã®ã§ã¯ãªãã人çãç°¡çŽ åããããã«å¿
èŠã§ãã
çç±2ïŒäžçŽç©ãšåéã®ãããã¯ã¯ãŸã£ããå
¬éãããŠãããããããããå€ãã®å©ç¹ãæåŸ
ã§ããŸããçç±3ïŒããã©ãŒãã³ã¹ãšå®å®æ§ãå¿
èŠã§ããããã§ãã³ãŒãã¯æŠå¿µå®èšŒã«éããŸãããéåžžã«é
ããéåžžã«é«éã«ããããšãã§ããŸãããšã©ãŒãã§ãã¯ã§ãåé¡ã¯ãããŸãããçç±4ïŒã»ãšãã©ãã¹ãŠã®ã¯ã©ã¹ãã€ã³ã¿ãŒã»ããããŸãããã€ã³ã¿ãŒãã§ãŒã¹ã®ã€ã³ã¿ãŒã»ããã¯ã©ãã§ããïŒçç±5ïŒãŸã å°ãçç±ããããŸããïŒãããã«
åã蟌ã¿ãªã©ãè¡ããã«ã¯ãªãŒã³ãªãããŒãžã³ãŒãã§AOPãå®è£
ããæè¡çãªå®çŸå¯èœæ§ãå®èšŒãããåªããã³ã³ãã¯ããªãããã¿ã€ãããããŸããAOPã«ã€ããŠç解ããã®ã§ãç¬èªã®å®è£
ãäœæã§ããŸãã次ã«ã翻蚳è
ã玹ä»ãããã®ã£ã°ãéã³å§ããŸã
ãã®ã»ã¯ã·ã§ã³ã«ã€ããŠã¯èè
ã«å®å
šã«åæããŸãããhabahabr.ruãcodeproject.comãªã©ã®ãããªãµã€ãã¯ãç°ãªã人ã
ãèšäºãæçš¿ããŠãããšããçç±ã ãã§ååšããŸãããªã圌ããããããããã¯åé¡ã§ã¯ãããŸãããããã®äœæ¥ã¯è¡ãããŠããŸããèè
ãç¡èŠããªãã§ãã ãããèšäºãæ°ã«å
¥ããªãã£ãå Žåã¯ãã³ã¡ã³ãã§èª¬æããŠãã ããããã€ãã¹ã®å Žåã誰ãããè¯ãæ¹æ³ãç¥ããŸãããæ°ã«å
¥ã£ãããé»ã£ãŠã¯ãããŸããïŒãããŠä»ã確ãã«ç¿»èš³è
ã®ã®ã£ã°
ïŒAOPãæ©èœããªãã£ããããå®ã¯ãç§ã®é©ãã®æ£æ°ã«ç§ã¯ãã®ããã®ã³ã¡ã³ãã¯ã以äžã®æ¡ä»¶ã®ããã«è¯ããšç°¡åãªãã·ã¢èªã®åèªææ¡ã§ããããšãææ¡ããå€ãã®åèªã翻蚳â¢ã¢ã¹ãã¯ããïŒãŸã ç解ã§ããããã ããïŒâ¢æžå¿µâ¢ãžã§ã€ã³ãã€ã³ãâ¢ã¯ãã¹ã«ããâ¢ãŠã£ãŒãã³ã°ïŒ weaver-äœããããŸãããããã·ã¢èªãèŠã€ããæ¹ãè¯ãã§ãããïŒèè
ïŒGuirec Le Bars