As far as I understand this concept  some questions rise like,

Where domain objects live?
Where mappers live?
Where and how to access them?


So Matthew for your example of service layer what does fetch() method
includes?

class BlogResource
   {
       public function create($data)
       public function fetch($id)
       //so on
   }



is it something like;

public function fetch($id){
     $entry = new Application_Model_EntryMapper();
     return   $entry->find($id);
}

?

If yes, most complexity and logic of application will dwell in mappers. Is
it true?

Thank you again and again




On Wed, Feb 23, 2011 at 11:57 PM, Matthew Weier O'Phinney
<[email protected]>wrote:

> -- Serkan Temizel <[email protected]> wrote
> (on Wednesday, 23 February 2011, 06:09 PM +0200):
> > After a question about sending mail from controller or model (it is
> > here<
> http://zend-framework-community.634137.n4.nabble.com/send-mail-notices-from-the-controller-or-model-td3319085.html
> >*)
> > I got some unexpected answers. Jurian mentioned  about a service
> approach.
> > After this post I made some search about services and  found this
> > article<
> http://www.angryobjects.com/2009/03/30/writing-robust-php-backends-with-zend-framework/
> >**
> >
> > Leendert Brouwer's article was on something totally new for me. Because
> it
> > was adding a new layer to MVC, a service layer. domain objects and
> mappers
> > are also new to me.
> >
> > I searched the web for documents about this new concept but I found
> nearly
> > no helpful resource.
> >
> > I need some valuable resource and coding and structuring samples about
> this
> > approach.
>
> Martin Fowler's "Patterns of Enterprise Application Architecture" has a
> section on Service Layers. I've also spoken about them a number of times
> in several presentations I've done (http://slideshare.net/weierophinney).
>
> Basically, think of the Service Layer object as the public API of your
> application or resource: these are the things you can do.
>
> As a quick pseudo-code example:
>
>    class BlogResource
>    {
>        public function create($data)
>        public function fetch($id)
>        public function update($id, $data)
>        public function delete($id)
>        public function fetchRecent()
>        public function fetchByYear($year)
>        public function fetchByMonth($month, $year)
>        public function fetchByDay($day, $month, $year)
>        public function fetchByTag($tag)
>    }
>
> I typically also compose something like the new ZF2 EventManager or a
> pubsub implementation of some sort, which allows me to tie into specific
> actions in order to introduce such things as ACL checks, etc. The
> service object then takes care of interacting with my various domain
> entities, mappers, etc.
>
> Your MVC application then is simply passing input to the service object,
> and handing the response off to the presentation layer. As an example:
>
>    class BlogController extends Zend_Rest_Controller
>    {
>        public function init()
>        {
>            $this->resource = new BlogResource();
>            // optionally configure this: inject the data access layer
>            // and/or mapper, tie in event handlers, etc.
>        }
>
>        public function indexAction()
>        {
>            $this->view->entries = $this->resource->fetchRecent();
>        }
>
>        public function getAction()
>        {
>            if (!$id = $this->getRequest()->getQuery('id', false)) {
>                throw new DomainException('Missing identifier');
>            }
>            $this->view->entry = $this->resource->fetch($id);
>        }
>
>        public function postAction()
>        {
>            if (!$data = $this->getRequest()->getPost('entry', false)) {
>                throw new DomainException('Missing data; cannot create
> entry');
>            }
>            $this->view->entry = $this->resource->create($data);
>        }
>
>        public function putAction()
>        {
>            if (!$id = $this->getRequest()->getQuery('id', false)) {
>                throw new DomainException('Missing identifier; cannot
> update');
>            }
>            if (!$data = $this->getRequest()->getPost('entry', false)) {
>                throw new DomainException('Missing data; cannot update
> entry');
>            }
>            $this->view->entry = $this->resource->update($id, $data);
>        }
>
>        public function deleteAction()
>        {
>            if (!$id = $this->getRequest()->getQuery('id', false)) {
>                throw new DomainException('Missing identifier; cannot
> delete');
>            }
>            $this->view->status = $this->resource->delete($id);
>        }
>
>        public function fetchByYearAction()
>        {
>            $year = $this->getQuery('year', date('Y'));
>            $this->view->entries = $this->resource->fetchByYear($year);
>        }
>
>        // etc...
>    }
>
> You'll notice that the individual action methods are succinct, and
> simply proxy to the service object, after first marshalling the input.
>
> Later, you can hook the same service object up to one of the server
> classes:
>
>    $json = new Zend_Json_Server();
>    $json->setClass($blogResource, 'blog');
>    $response = $json->handle();
>    echo $response;
>
> Basically, you're writing a re-usable application layer that simply
> needs something to provide input, and another layer to produce the
> presentation.
>
> > More importantly I need your opinions about this approach. Why ZF
> > don't ship with a service layer or default mapper? Are they really
> > needed or they just increase the complexity?
>
> We don't ship a mapper because, frankly, ORM solutions are the sort of
> thing that need entire teams to get right, and there's a great solution
> out there already: Doctrine 2.
>
> Regarding a service layer, we can't really ship a service layer by
> default -- service layers are highly application-specific (as is the
> entire domain model). About the most we could likely ship is an
> interface for RESTful resources, and a "base controller" for RESTful
> resources that expects to instantiate a RESTful resource and which would
> provide the basic functionality as outlined in the controller above
> (this would be for basic CRUD operations only). I'm definitely
> considering this for ZF2, as it would streamline many common workflows
> -- but you'd still be responsible for writing the various domain
> entities, wiring in an ORM (if used), etc.
>
> --
> Matthew Weier O'Phinney
> Project Lead            | [email protected]
> Zend Framework          | http://framework.zend.com/
> PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
>

Reply via email to