ZFåå¼·ä¼#2ãã©ãã¼ã¢ãã Zend Frameworkã§ã¢ãã«ãå§ããåã«ç解ãã¦ãããããã¨
Zend Framework勉強会#2 ã¯GMOペパボ株式会社æ§ã®ååããã£ã¦ãçæ³ã§ããããã©ããZend_Dbã«é¢ãã¦èª¤è§£ããããããªæ°ããã¦ããã®ã§(ç§ãå«ãã¦ï¼ä¸éã確èªãã¦ã¿ããã¨ãããã©ãã¼ã¢ããè¨äºã§ãã
Zend Frameworkã§å¯¾å¿ãã¦ããã¢ãã«æ§æã¯ããã¡ã¤ã³ã¢ãã«+ãµã¼ãã¹ã¬ã¤ã¤ã¼ã§ç´æ¥çã«ã¯データマッパーã§ãã
CakePHPã§ã¯æ¨æºã§ã¯ActiveRecordãæ¡ç¨ãã¦ããã¨æãã¾ããããããCakePHPãsymfonyã§å¦ç¿ãã¦ãã人ãä¸çªæåã«æ¸æãé¨åã§ã¯ãªããã¨æãã¾ããã¾ããåå¦è
ããã¼ã¿ãããã¼ã®æ義ããããªãç解ããã®ã¯é£ãããããªæ°ããã¾ãã
è¦ã¯ãå¤ãã®åå¿è ãâã¢ãã«ã£ã¦ãDBãã¼ãã«ã®ãã¨ã ããâã¨èãã¦ãã¾ãã®ã¯ãããªããã¨ãçµæçã«ã³ã³ããã¼ã©ããµããããããUnitTestã§å½±é¿ãåºã¦ãã¾ããã¨ãã話ã«ãªã£ã¦ãã¾ãã
- -
CakePHPã®ããããé£ã¹æ¹ãã
http://cakephp.seesaa.net/article/99302070.html
ä»ã§ã¯ãåå¿è
ã«éããªããªã£ã¦ãã¦ããããã«æãã¾ãã
å
è¨äºã¯Keeping it Simple: ActiveRecord does not suckãã¡ãã§ãããZend Frameworkã®ã¡ã¤ã³éçºè
ã®æ¹ã®ã³ã¡ã³ãã¨ãã¦ãModel !== Databaseã ã¨ãã主張ãæ確ã«è¿°ã¹ããã¦ãã¾ãã
å ¬å¼ããã¥ã¡ã³ãã確èªãã¦ã¿ã
Zend Frameworkã®公式ドキュメントのクィックスタートã«ããã°(http://d.hatena.ne.jp/netjockey/20090702/p1 ï¼æ¥æ¬èªè¨³))
- Zend_Db_Table
- Zend_Db_Table_Row
- zfã³ãã³ãã§ä½æããããããã¼
ãä»ã®ã¨ããZend Frameworkã¨Zend_Dbã§ä½æããã¢ãã«ã®æ¨æºæ§æã¨ç解ãã¦ããã¨æãã¾ããzfãã¼ã«ããµãã¼ããã¦ãã¾ãã
誤解ãæããã«ã端çãªéããæ¸ã
- DoctrineãCakePHPã§æ¡ç¨ããã¦ããActiveRecordã¨Zend_Db_Table_Row(ãã¼ãã¼ã¿ã²ã¼ãã¦ã¨ã¤ï¼ã®éã
ActiveRecord | ãã¼ã¿ã¢ã¯ã»ã¹ãªãã¸ã§ã¯ãã«ãã¡ã¤ã³ãã¸ãã¯ãå«ã |
---|---|
Row Data Gateway | ãã¼ã¿ã¢ã¯ã»ã¹ãªãã¸ã§ã¯ãã«ãã¡ã¤ã³ãã¸ãã¯ãå«ã¾ãªã |
- ActiveRecordã¨ãã¼ã¿ãããã¼ã®æ±ºå®çãªéã
ActiveRecord | ãã¡ã¤ã³ã¯ãã¼ã¿ã½ã¼ã¹ãç¶æ¿ |
---|---|
Data Mapper | ãã¡ã¤ã³ã¨ãã¼ã¿ã½ã¼ã¹ã®åé¢ãä»²ä» |
â»ãããã¼ããåå¾ãããã¡ã¤ã³ã¢ãã«ã«ã¯ãã¼ã¿ã¢ã¯ã»ã¹æ©è½ã¯ãªã
ããããè¨ãããã¨
ActiveRecordããã¼ã¿ã½ã¼ã¹ãå å ãããã¸ãã¹ãã¸ãã¯ã®å®è£ ãªã®ã«å¯¾ãã¦ããã¼ã¿ãããã¼ã¯ãã¡ã¤ã³ã¨ãã¼ã¿ã½ã¼ã¹ã®åé¢ãç®çã«ãã¦ããã®ã§ãå¿åæ§ãå ¨ãéã«ãªãã¾ãã
ãã¡ã¤ã³ã¢ãã«ã®åæè¨è¨ã§æåã«å¤æããã¹ãé¸æã¯ãã¢ã¯ãã£ãã¬ã³ã¼ãããã¼ã¿ãããã¼ã®ãããã使ç¨ãããã§ããã
- -
PofEAAã®10.3.2
ãã¼ã¿ãããã¼ã¯ã¢ã¼ããã¯ãã£çã«ã¯Domain-Driven Designã¨ã®ç¸æ§ãããã§ããã軽éã§ã¯ãªã¼ã³ãªãã¡ã¤ã³ãæ§æããã®ã«å½¹ç«ã¡ã¾ãã
ä¸æ¹ãActiveRecordã¯RDBMSã軸ã¨ããã¢ããªã±ã¼ã·ã§ã³ã®å®è£
ãé«éåããã®ã«å½¹ç«ã¡ã¾ãããªãã¸ã§ã¯ãããå³ä¿åãããã¨ãããã¨ã§å®è£
è
ããè¦ãéææãé«ãã§ãã
ã¯ãªã¼ã³ãªã¢ãã«ãç®æããªãDDDãã¹ãã¼ãã追æ±ãããªãActiveRecordã¨ããå³å¼ã¯ããããçã¾ãããã®ã¨æãã¾ãããä¸æ¹ã§ãDDDã®å®è£
ã¹ãã¼ããå¿
ãããé
ããªãã¨ããç¹ãActiveRecordãè¤éãªãã¡ã¤ã³ãæ±ããªãããã§ã¯ãªãã¨ããç¹ã§ãææ³ã®éãã¯ãããã§ãããã¨ã«å¤§ããªéããããããã§ã¯ãªãã¨ã¯æãã¾ãã
ãã®ãããActiveRecordããã¼ã¿ãããã¼ãã¨ããè°è«ã¯å²å¦çã§ãå®è·µçã§ã¯ãªãã¨ããæ¹å¤ãåãããã¨ãããã¾ãããã ãããã¯ã©ã¡ãããé¸æãã¦é²ã¿ããããã°ããããã§ãææç©ãå¾ããããã¨ã§ãæ··åãã¦ä½¿ã£ãå ´åã«ã¯ä¸¡æ¹ã®è¯ããé£ãã¤ã¶ããã¨ã¯ééããªãã¨æãã¾ãã
AcriveRecord or Data Mapper
ã§ã¯ãåªå£ã®è©±ã§ã¯ãªãã¨ããåæã§ãZend Frameworkã§ã¢ãã«ãå®è£
ãããªãã©ãããã¹ãã§ããããã
ãã¼ã¿ãããã¼ã¨ActiveRecordã¯ç®çã®é¨åã§å¤§ããããé¢ãã¦ããã®ã§æ··åãã¦ä½¿ãã®ã¯çãæªãã¨ãã¦ãè¨è¨åæã«ã©ã¡ãããé¸æããå¿
è¦ãããã¾ãã
Zend_Dbãçãããªããã¼ã¿ãããã¼ãæ£è§£ã
Zend_Dbã¯ActiveRecordããµãã¼ããã¦ããªãã®ã§ãActiveRecordãæ§æãããã¨ãã¦ãZend_Db_Table_Rowãæ¡å¼µãããã¨ããã¨ãæãããã³ã¼ãéãå¢ãã¦ãã¾ãã¾ããã¤ã¾ããZend Frameworkã§CakePHPçãªå®è£
ããããã¨ããã®ã¯å¹çãæªãã¨æãã¾ããã¨ããããZend Frameworkãé¸ã¶çç±ã¯ActiveRecord以å¤ã使ãããããã£ã¦ã®ããããã«ãããã®ã¨æã£ã¦ããã§ãããã©ããªãã§ãããã»ã»ã»
ã§ãã®ã§ãZend_Dbã使ããªããã¼ã¿ãããã¼ãæ£è§£ãã¨ã
AcriveRecordãªãDoctrine
ActiveRecordã§ä½¿ããã·ã¹ãã ãä½ã£ã¦ããã«ã¯ãã©ã¤ãã©ãªå´ã®å
å®ãæ¬ ãããªãã¨æãã¾ããZend_Dbã¯Doctrineã§è¨ãã°ãDBAL(Database Abstraction Layer)ã«ããã¾ããã
http://www.doctrine-project.org/documentation/manual/1_2/en/introduction#basic-overviewåç
§
ãããªä¸ã§ARãèªä½ããã®ã¯ããã¾ãã«ãã³ã¹ããé«ãã¨æãã¾ãããã¡ããä½ãã®ã¯èªç±ã§ãããZend Frameworkã¨Doctrineã¨ã®é£æºã¯ãã»ã©é£ããã¯ãªãã®ã§ãActiveRecordãããããã°Doctrineã®æ¡ç¨ãæ¤è¨ããã¹ãã ã¨æãã¾ãã
Zend Framework (æ¥æ¬ï¼ã§Data Mapperãæ¡ç¨ããã¨ãã®æ³¨æ
æ¥æ¬ã®PHPãã¬ã¼ã ã¯ã¼ã¯çã§CakePHPã¯ä¸åã®äººæ°ãèªã£ã¦ãã¾ãããéããsymfonyãDoctrineã®æ¡ç¨ã§ActiveRecordå´ã«ã¤ãã¦ãã¾ãããã®ãããæ¥æ¬èªã§ã®Webçµç±ã®æ
å ±éã§ã¯ã¢ãã«ï¼ActiveRecordãå§åçã§ãã
ãã¼ã¿ãããã¼ã使ããªãï¼=Zend_Dbã使ããªã)ãéçºè
éã®æèã®ãºã¬ãè£ãããActiveRecordã¨å¯¾æ¯ãã¦Data Mapperã¨ã¯ã©ããã£ããã®ãªã®ããã確èªãã¦ããå¿
è¦ãããããã«æãã¾ãããã¼ã¿ãããã¼èªä½ã¯é£ãã話ã§ã¯ãªããZFå
¬å¼ããã¥ã¡ã³ãã®quick-startã§ååã ããã¨æãã¾ãããActiveRecordã¨ã®éãã¯æ確ã«ãã¦ããã¨ããã¨æãã¾ãã
ã¢ãã«ããã®ä»ã®é¸æè¢
ãã¦ãZend_Dbã¯DALã ã¨ãã話ã§çµãã£ã¦ãã¾ãã¨ã空æ´ã«ãã¦ããã°ãªãã§ãããããã¨ãã話ã«ãªã£ã¦ãã¾ãã¾ãããæå¤ã¨ããã§ã¯ãªãã»ã»ã»
- Zend_Db_Tableã¨Table Moduleãã¿ã¼ã³
Table Module | ãã¼ãã«ã«å¯¾ããè¤æ°ã®ãã¡ã¤ã³ãã¸ãã¯ãå«ãæä½ã®ã«ãã»ã«å |
---|---|
Table Data Gateway | ãã¼ãã«ã«å¯¾ãããã¼ã¿ã½ã¼ã¹æä½ã®ã«ãã»ã«å |
Zend_Db_Tableã¯ãã¼ãã«ãã¼ã¿ã²ã¼ãã¦ã¨ã¤ã§ãããããã¨é£æºãããã¼ãã«ã¢ã¸ã¥ã¼ã«ãæ¸ãã¨è¨ãæ¹åæ§ã¯å®ã¯æ¥æ¬ã®Webã¢ããªã«æé©ã ã£ãããã¾ããããã«ã¤ãã¦ã¯ãã¾ãå¾æ¥ãã¾ããå ´åã«ãã£ã¦ã¯ããããããã ããªãã¢ã¼ããã¯ãã£è«äºãããå¿ è¦ã¯ãªãããã£ã±ãZend_Db_Table_Adapterã¨çã¯ã¨ãªã§ååã¨ãããã¨ãè¨ãã¾ãã
Zend_Db_Selectã§ORM/ã¯ã¨ãªãªãã¸ã§ã¯ã
ãã¡ããå¾æ¥ã
ã§ãæ··åã¯ãªãã
ãã®ä»ã®
çºè¡¨é¢ä¿ã®è³æã¯Zend Framework勉強会#2 で使用した資料他 - noopな日々ã§ãªã³ã¯ãã¦ãã¾ãããä¸ã®ã¹ã©ã¤ãã¯ãZend Frameworkã®ã¢ãã«ã«ã¤ãã¦è©±ãäºå®ã«ãã¦ãã¦å稿ãç¨æãã¦ããã®ã§ããããã¿ããã¶ãããªã¨ããã®ããã£ã¦æ²¡ç¨¿ã«ãã¦ãããã®ã§ããPofEAAé¢é£ã®è©±ãæµãèªã¿ã§ããããã«å³è§£ãã¦ããã¾ãããããããããã°ããããã ããã
ä»ã®æ¹ã®æè¦ãªã©
-- åæ訳 --
Zend Frameworkã¯ActiveRecordã§ã¯ãªãã代ããã«ããã¼ãã«ãã¼ã¿ã²ã¼ãã¦ã¨ã¤ã¨ãã¼ãã¼ã¿ã²ã¼ãã¦ã¨ã¤ãã¿ã¼ã³ã使ãããã¼ãã¼ã¿ã²ã¼ãã¦ã¨ã¤ã®ãã¼ã¿ãã¢ãã«ã«ãããããã®ã«ãã¼ã¿ãããã¼ã使ãã¾ãããªããªããã¢ãã«ããã¼ã¿ãã¼ã¹ãã¼ãã«ã¨1:1ã«ãããã³ã°ãã¦ããªãã¨ActiveRecordã¯æç«ããªãããã§ãã
- -
Zend Framework does not use ActiveRecords but instead uses the Table Data Gateway and Row Data Gateway pattern, and uses a DataMapper to map the contents of the Row Data Gateway to the model, because ActiveRecord breaks down when your models don't have a 1:1 mapping to your database tables.
http://stackoverflow.com/questions/1016966/does-the-datamapper-pattern-break-mvc
ã¨ãã話ãããã¾ãããè¨ãéãã§ãActiveRecordãæªè
ã«ããã»ã©Zend Frameworkã¯å²æ
¢ã§ã¯ãªãã¨æãã¾ããå®éãActiveRecordããµãã¼ãããã¹ããDoctrineã¨ã®é£æºãªã©ããããããã«ãªãã¤ã¤ããã¾ãã
ã¾ããDomain-Driven Designã¨ã®å¯¾æ¯ã§ã¯ã
-- åæ訳 --
Domain-Driven Designãèæ ®ããã¨ãZend Frameworkã¯ãDDD/Repositoriesã®ä»£ããã«ããã¼ã¿ãããã¼ã使ã£ã¦ãã¾ããããã§DDDã¨è¨ãããï¼ ãã¼ãã³ãã¦ã©ã¼ã«ãããªãã¸ããªã®è§£éã§ã¯ãããã¯NOã ããEric Evansã«ããã°ãDDDã®Repositoryã¯ã·ã³ãã«ã«ã§ããã¨è¨ã£ã¦ããããã®æãã·ã³ãã«ãªRepositoryã¯ãã¼ã¿ãããã¼ã ã¨å½¼ã®èæ¸ã®ä¸ã«æ¸ãã¦ããã¾ãã
The Zend Framework is using DataMappers instead of Repositories. Is this really DDD-ish? Well, Fowler's interpretation of a Repository might say no. However, Eric Evans states that a DDD Repository can be very simple. At its simplest, a Repository is a DataMapper (See DDD book).
ã¨è¨ãå
·åã«ããã¼ã¿ãããã¼ã¯DDDã®ãªãã¸ããªã¨ãã¦ä½¿ã£ã¦ãåé¡ãªãã ããã¨ããæè¦ããããç§ãããæãã¾ãã
ã¾ãããã¼ã¿ãããã¼ããã¼ãã¼ã¿ã²ã¼ãã¦ã¨ã¤ãRepositoryãæ§æããææã«ãªã£ã¦ãããã¨ã¯ééããªãã®ã§ãé«åº¦ãªRepositoryãçµãã®ã«Zend_Dbé¢ä¿ããã¾ãå©ç¨ããã®ã«é害ã¯ããã¾ããã
ORMã¨ãã¦ActiveRecordçã«å®è£
ããã®ããã¡ãã¨è¨ãã¨ãããªãã¨ã¯ãªããZend_Db_Table_RowãActiveRecordçã«ä½¿ã£ã¦ãããã¨æãã¾ãããã ãä»ã®ã¨ãããDoctrineãªã©ã®å¤é¨ã©ã¤ãã©ãªã使ãã«ãã¦ããZend_Db_Table_Rowã使ãã«ãã¦ããActiveRecordçãªå®è£
ãè¡ãã«ã¯ããã¤ãã®ããªãã¯ã¨è¨å¤§ãªå·¥æ°ãå¿
è¦ã¨ãããã§ãã
ã¾ããããã楽ãããã§ããã©ãã