title: How to implement pagination in DDD?
body: <p>I have users and groups. Each user can have any number of groups. I want to show user groups in paginated form, n groups at a time. I know how to implement an ordinary pagination, however I don't know how to integrate it into my Domain Driven Design <b>(and without leading to code duplication later)</b>. I would like it to work something like this:</p>
  
  <pre><code>$adapter = new DatabaseAdapter(...);
  $userRepository = new UserRepository($adapter);
  $user = $userRepository-&gt;fetchById(1);
  $groups = $user-&gt;getGroups()-&gt;getRange($offset, $limit);
  </code></pre>
  
  <p>and the same for other domain entities:</p>
  
  <pre><code>$projects = $user-&gt;getProjects()-&gt;getRange($offset, $limit);
  ...
  </code></pre>
  
  <p>Simplified, my code looks like this:</p>
  
  <pre><code>class Group
  {
      private $_id;
      private $_name;
  
      public function __construct($id, $name) {
          $this-&gt;setId($id);
          $this-&gt;setName($name);
      }
  
      public function setId() {
          $this-&gt;_id = $id;
      }
  
      public function getId() {
          return $this-&gt;_id;
      }
  
      public function setName($name) {
          $this-&gt;_name = $name
      }
  
      public function getName() {
          return $this-&gt;_name;
      }
  }
  
  class Groups
  {
      private $_elements = array();
  
      public function __construct(array $groups) {
          foreach($groups as $group) {
              if(!($group instanceof Group)) {
                  throw new Exception();
              }
              $this-&gt;_elements[] = $group;
          }
      }
  
      public function toArray() {
          return $this-&gt;_elements;
      }
  }
  
  class GroupMapper
  {
      private $_adapter;
  
      public function __construct(DatabaseAdapterInterface $adapter) {
          $this-&gt;_adapter = adapter;
      }
  
      public function fetchById($id) {
          $row = $this-&gt;_adapter-&gt;select(...)-&gt;fetch();
          return $this-&gt;createEntity($row);            
      }
  
      public function fetchAll() {
          $rows = $this-&gt;_adapter-&gt;select(...)-&gt;fetchAll();
          return $this-&gt;createEntityCollection($rows);
      }
  
      private function createEntityCollection(array $rows) {
          $collection = array();
          foreach($rows as $row) {
              $collection[] = $this-&gt;createEntity($row);
          }
          return $collection;
      }
  
      private function createEntity(array $row) {
          return new Group($row['id'], $row['name']);
      }
  }
  
  
  class User
  {
      private $_id;
      private $_name;
      private $_groups;
  
      public function getId() {
          return $this-&gt;_id;
      }
  
      public function setName($name) {
          $this-&gt;_name = $name;
      }
  
      public function getName() {
          return $this-&gt;_name;
      }
  
      public function setGroups($groups) {
          $this-&gt;_groups = $groups;
      }
  
      public function getGroups() {
          return $this-&gt;_grous;
      }
  }
  
  class UserRepository
  {
      private $_userMapper = null;
      private $_groupMapper = null;
  
      public function __construct(DatabaseAdapterInterface $adapter) {
          $this-&gt;_groupMapper = new GroupMapper($adapter);
          $this-&gt;_userMapper = new UserMapper($adapter);
      }
  
      public function fetchById($id) {
          $user = $this-&gt;_userMapper-&gt;fetchById($id);
          if($user) {
              $groups = $this-&gt;_groupMapper-&gt;fetchAllByUser($id);
              $user-&gt;setGroups($groups);
          }
      }
  
      public function fetchAll() {
          ...
      }
  }
  </code></pre>
  
  <p>Thank you for your help!</p>