GitHub PullRequestReviewCommentEvent at 2014-04-06 05:56:44
Repository: guideline
Actor: kazuki43zoo
Payload: {"comment":{"url":"https://api.github.com/repos/terasolunaorg/guideline/pulls/comments/11324686","id":11324686,"diff_hunk":"@@ -0,0 +1,2013 @@\n+Domain Layer Implementation\n+================================================================================\n+\n+.. contents:: Index\n+   :local:\n+   :depth: 3\n+\n+Roles of domain layer\n+--------------------------------------------------------------------------------\n+Domain layer \\ **implements business logic**\\ to be provided to the application layer.\n+\n+Implementation of domain layer is classified into the following.\n+\n+ .. list-table::\n+   :header-rows: 1\n+   :widths: 10 30 60\n+\n+   * - S.No.\n+     - Classification\n+     - Description\n+   * - | 1.\n+     - | :ref:`domainlayer_entity`\n+     - | Creation of classes (Entity class) to hold business data.\n+   * - | 2.\n+     - | :ref:`repository-label`\n+     - | Implementation of the methods to operate on business data. These methods are provided to Service classes. \n+       | These are in particular the CRUD operations on Entity object.\n+   * - | 3.\n+     - | :ref:`service-label`\n+     - | Implementation of the methods for executing business logic. These methods are provided to the application layer.\n+       | Business data required by the business logic is fetched as the Entity object through the Repository.\n+\n+This guideline recommends the structure of creating Entity classes and Repository for the following reasons.\n+\n+#. \\ **By splitting the overall logic into business logic (Service) and the logic to access business data, the implementation scope of business logic gets limited to the implementation of business rules**\\ , \n+#. \\ **Access logic to business data is standardized**\\  by consolidating the operations of business data in the Repository. \n+\n+ .. note::\n+\n+    Though this guideline recommends a structure to create Entity classes and Repository, it is not mandatory to perform development in this structure.\n+\n+    Decide a structure by taking into account the characteristics of the application as well as the project (structure of development team and development methodology).\n+\n+Flow of development of domain layer\n+--------------------------------------------------------------------------------\n+| Flow of development of domain layer and allocation of roles is explained here.\n+| A case where application is created by multiple development teams is assumed; however, the flow itself remains same even if developed by a single team.\n+\n+ .. figure:: images/service_implementation_flow.png\n+    :alt: implementation flow of domain layer\n+    :width: 100%\n+    :align: center\n+\n+ .. list-table::\n+    :header-rows: 1\n+    :widths: 10 20 80\n+\n+   * - S.No.\n+     - Team in-charge\n+     - Description\n+   * - | (1)\n+     - | Common development team\n+     - | Common development team designs and creates Entity classes.\n+   * - | (2)\n+     - | Common development team\n+     - | Common development team works out access pattern for the Entity classes extracted in (1) and designs methods of Repository interface.\n+       | Common development team should implement the methods to be shared by multiple development teams.\n+   * - | (3)\n+     - | Common development team\n+     - | Common development team provides Entity classes and Repository created in (1) and (2) to the business application development team.\n+       | At this time, it requests each business application development team to implement the Repository interface.\n+   * - | (4)\n+     - | Business application development team\n+     - | Business application development team takes charge of the implementation of Repository interface.\n+   * - | (5)\n+     - | Business application development team\n+     - | Business application development team develoops Service interface and Service class using the Entity class and Repository provided by \n+       | the common development team and the Repository implementation class created by the team itself.\n+\n+ .. warning::\n+\n+    A system having a large development scope is often developed by assigning the application to multiple teams.\n+    In that case, it is strongly recommended to provide a common team to design Entity classes and Repository.\n+\n+    When there is no common team, O/R Mapper(Mybatis) should be called from Service directly without creating Entity classes and Repository.\n+\n+.. _domainlayer_entity:\n+\n+Implementation of Entity\n+--------------------------------------------------------------------------------\n+\n+Method of creating Entity class\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+| Create an Entity using the following method.\n+| Specific creation method is shown in \\ :ref:`domainlayer_entity_example`\\.\n+\n+ .. list-table::\n+   :header-rows: 1\n+   :widths: 10 35 55\n+\n+   * - S.No.\n+     - Method\n+     - Supplementary\n+   * - | 1.\n+     - | Create Entity class for each table.\n+     - | However, Entity class is not required for mapping tables which represent the the relationship between the tables.\n+       | Further, when the tables are not normalized, Entity class for each table rule may not be applible. Refer to the \\ :ref:`Warning as well as Note outside this \n+       | table <domainlayer_entity_policy_warning_note>`\\  for the approach related to not-normalized tables.\n+   * - | 2.\n+     - | When there is a FK (Foreign Key) in the table, the Entity class of FK destination table must be defined as one of the properties of this Entity.\n+     - | When there is 1:N relationship with FK destination table, use either \\ ``java.util.List<E>``\\  or \\ ``java.util.Set<E>``\\.\n+       | The Entity corresponding to the FK destination table is called as the related Entity in this guideline.\n+   * - | 3.\n+     - | Treat the code related tables as \\ ``java.lang.String``\\  rather than as an Entity.\n+     - | Code related tables are to manage the pairs of code value and name.\n+       | When there is a need to bifurcate the process as per code values, ``enum`` class corresponding to code value should be created and it must be defined as property.\n+\n+.. _domainlayer_entity_policy_warning_note:\n+\n+ .. warning::\n+\n+    When table is not normalized, **check whether to use the method of creating the Entity classes and Repository** by considering the following points.\n+    Since the unnormalized tables do not have good compatiblity with JPA, it is better not to use JPA.\n+\n+    * | Creating an appropriate Entity class may often not be possible because of increased difficulty in creating entities if the tables are not normalized.\n+      | In addition, efforts to create an Entity classes also increases.\n+      | Two viewpoints must be taken into consideration here. Firstly \"Can we assign an engineer who can perform normalization properly?\" and secondly \"Is it worth \n+      | taking efforts for creating normalized Entity classes?\".\n+    * | If the tables are not normalized, the logic to fill the gap of differences between the Entity class and structure of table is required in data access.\n+      | Here the viewpoint to be considered is, \"Is it worth taking efforts to fill the gap of differences between the Entity class and structure of table ?\".\n+\n+    The method of creating Entity classes and Repository is recommended; however, the characteristics of the application as well as the project (structure of \n+    development team and development methodology) must also be taken into account.\n+    \n+.. _domainlayer_entity_policy_note:\n+\n+ .. note::\n+\n+    If you want to operate on business data with normalized Entity classes - even if the tables are not normalized - it is recommended to use Mybatis as an \n+    implementation of RepositoryImpl of the infrastructure layer.\n+\n+    Mybatis is the O/R Mapper developed to map the SQL with object and not to map the database table record with object. So depending on the implementation \n+    of SQL, mapping to the object independent of table structure is possible.\n+\n+\n+.. _domainlayer_entity_example:\n+\n+Example of creating Entity class\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+| The creation of Entity class is explained using specific examples.\n+| Following is an example of creating the business data of Entity classes required for purchasing a product on some shopping site.\n+\n+Table structure\n+\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n+The table structure is as given below:\n+\n+ .. figure:: images/service_entity_table_layout.png\n+    :alt: Example of table layout\n+    :width: 100%\n+    :align: center\n+\n+ .. list-table::\n+    :header-rows: 1\n+    :widths: 10 20 15 55\n+\n+    * - S.No.\n+      - Classification\n+      - Table name\n+      - Description\n+    * - | (1)\n+      - | Transaction related\n+      - | t_order\n+      - | Table to store orders. 1 record is stored for 1 order.\n+    * - | (2)\n+      - |\n+      - | t_order_item\n+      - | Table to store the products purchased in 1 order. Record of each product is stored when multiple products are purchased in 1 order.\n+    * - | (3)\n+      - |\n+      - | t_order_coupon\n+      - | Table to store the coupon used in a single order. Record of each coupon is stored when multiple coupons are used in 1 order. No record is stored when coupon is not used.\n+    * - | (4)\n+      - | Master related\n+      - | m_item\n+      - | Master table to define products.\n+    * - | (5)\n+      - |\n+      - | m_category\n+      - | Master table to define product category.\n+    * - | (6)\n+      - |\n+      - | m_item_category\n+      - | Master table to define the category of the product. Mapping between product and category is maintained. Model where 1 product belongs to multiple categories.\n+    * - | (7)\n+      - |\n+      - | m_coupon\n+      - | Master table to define coupons.\n+    * - | (8)\n+      - | Code related\n+      - | c_order_status\n+      - | Code table to define order status.\n+\n+\n+Entity structure\n+\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n+If Entity classes are created with the help of policy defined by the above table, it results into the following structure.\n+\n+ .. figure:: images/service_entity_entity_layout.png\n+    :alt: Example of entity layout\n+    :width: 100%\n+    :align: center\n+\n+ .. list-table::\n+    :header-rows: 1\n+    :widths: 10 15 65\n+\n+    * - S.No.\n+      - Class name\n+      - Description\n+    * - | (1)\n+      - | Order\n+      - | Entity class indicating 1 record of t_order table.\n+        | Multiple \\ ``OrderItem``\\ and \\ ``OrderCoupon``\\ are stored as the related Entity.\n+    * - | (2)\n+      - | OrderItem\n+      - | Entity class indicating 1 record of t_order_item table.\n+        | ``Item`` is stored as the related Entity.\n+    * - | (3)\n+      - | OrderCoupon\n+      - | Entity class indicating 1 record of t_order_coupon table.\n+        | \\ ``Coupon``\\  is stored as the related Entity.\n+    * - | (4)\n+      - | Item\n+      - | Entity class indicating 1 record of m_item table.\n+        | Multiple \\ ``Category``\\ are stored as the related Entity. The association between \\ ``Item``\\  and \\ ``Category``\\ is done using m_item_category table.\n+    * - | (5)\n+      - | Category\n+      - | Entity class indicating 1 record of m_category table.\n+    * - | (6)\n+      - | ItemCategory\n+      - | Entity class is not created since m_item_category table is the mapping table to store the relationship between m_item table and m_category table.\n+    * - | (7)\n+      - | Coupon\n+      - | Entity class indicating 1 record of m_coupon table.\n+    * - | (8)\n+      - | OrderStatus\n+      - | Entity class is not created since c_order_status table is code table.\n+\n+\n+As it can be observed from the above entity diagram, it might first seem that Order class is the only main entity class\n+in the shopping site application; however, there are other main entity class as well other than Order class.\n+\n+Below is the classification of main Entity classes as well as Entity class which are not main. \n+\n+ .. figure:: images/service_entity_entity_class_layout.png\n+    :alt: Example of entity layout\n+    :width: 100%\n+    :align: center\n+\n+|\n+\n+The following 4 Entities are treated as the main Entity for creating shopping site application.\n+\n+ .. list-table::\n+   :header-rows: 1\n+   :widths: 10 30 60\n+\n+   * - S.No.\n+     - Entity class\n+     - Reasons for treating as the main Entity.\n+   * - | (1)\n+     - | Order class\n+     - | It is one of the most important Entity class in the shopping site.\n+       | Order class is the Entity indicating the order itself and a shopping site cannot be created without the Order class.\n+   * - | (2)\n+     - | Item class\n+     - | It is one of the most important Entity class in the shopping site.\n+       | Item class is the Entity indicating the products handled in the shopping site and a shopping site cannot be created without Item class.\n+   * - | (3)\n+     - | Category class\n+     - | Product categories are displayed usually on the top page or as a common menu in shopping sites. In such shopping sites, Category becomes a main entity.\n+         Usually operations like 'search category list' can be expected.\n+   * - | (4)\n+     - | Coupon class\n+     - | Often discounts through coupons are offered in the shopping sites as a measure of promoting sales of the products. \n+       | In such shopping sites, Coupon becomes a main entity. Usually operations like 'search coupon list' can be expected.\n+\n+\n+The following are not main Entities for creating shopping site application.\n+\n+ .. list-table::\n+   :header-rows: 1\n+   :widths: 10 30 60\n+\n+   * - S.No.\n+     - Entity class\n+     - Reason of not treating Entity as main Entity\n+   * - | (5)\n+     - | OrderItem class\n+     - | This class indicates 1 product purchased in 1 order and exists only as the related Entity of Order class.\n+       | So OrderItem class should not be considered as main Entity.\n+   * - | (6)\n+     - | OrderCoupon\n+     - | This class indicates 1 coupon used in 1 order and exists only as the related Entity of Order class.\n+       | So, OrderCoupon class should not be considered as main Entity.\n+\n+\n+.. _repository-label:\n+\n+Implementation of Repository\n+--------------------------------------------------------------------------------\n+\n+Roles of Repository\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+Repository has following 2 roles.\n+\n+1. | **To provide to Service, the operations necessary to control Entity lifecycle (Repository interface).**\n+   | The operations for controlling Entity lifecycle are CRUD operations.\n+\n+ .. figure:: images/repository_responsibility_1.png\n+    :alt: provide access operations to entity\n+    :width: 100%\n+    :align: center\n+\n+\n+2. | **To provide persistence logic for Entity (implementation class of Repository interface).**\n+   | Entity object should persist irrespective of the lifecycle (start and stop of server) of application.\n+   | Mostly relational database is the permanent destination of Entity. However, NoSQL database, cache server, external system and file (shared disk) can also be the permanent destination.\n+   | The actual persistence processing is done using O/R Mapper API.\n+   | This role is implemented in the RepositoryImpl of the infrastructure layer. Refer to \\ :doc:`InfrastructureLayer`\\ for the details.\n+\n+ .. figure:: images/repository_responsibility_2.png\n+    :alt: persist entity\n+    :width: 100%\n+    :align: center\n+\n+\n+Structure of Repository\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+Repository consists of Repository interface and RepositoryImpl and performs the following roles.\n+\n+ .. figure:: images/repository_classes_responsibility.png\n+   :alt: persist entity\n+   :width: 100%\n+   :align: center\n+\n+ .. list-table::\n+   :header-rows: 1\n+   :widths: 10 20 30 40\n+\n+   * - S.No.\n+     - Class(Interface)\n+     - Role\n+     - Description\n+\n+   * - | (1)\n+     - | Repository interface\n+     - | Defines methods to control Entity lifecycle required for implementing business logic (Service).\n+     - | Defines methods for CRUD operations of the Entity and is not dependent on persistence layer.\n+       | Repository interface belongs to the domain layer since it plays the roles of defining the operations on Entity required for implementing business logic (Service).\n+\n+   * - | (2)\n+     - | RepositoryImpl\n+     - | Implements the methods defined in Repository interface.\n+     - | Implements CRUD operations of the Entity and is dependent on persistence layer. Performs actual CRUD processes using API that performs persistence provided by Spring Framework, O/R Mapper and middleware.\n+       | RepositoryImpl belongs to infrastructure layer since it plays the role of implementing the operations defined in Repository interface.\n+       | Refer to \\ :doc:`InfrastructureLayer`\\ for the implementation of RepositoryImpl.\n+\n+\n+| In case of multiple destinations in persistence layer, the resulting configuration as follows.\n+| due to this, the logic depending on persistence platform of Entity is hidden from business logic (Service).\n+\n+ .. figure:: images/repository_not_depends_on.png\n+   :alt: persist entity\n+   :width: 100%\n+   :align: center\n+\n+ .. note:: **Is it possible to hide 100% of persistence platform dependent logic from the Service class ?**\n+\n+    In some cases it cannot be hidden completely due to constraints of persistence platform and the libraries used to access the platform.\n+    As much as possible, platform dependent logic should be implemented in RepositoryImpl instead of Service class.\n+    When it is difficult to exclude the platform dependent logic and merits of doing so are less,\n+    persistence platform dependent logic can be implemented as a part of business logic (Service) process.\n+\n+    A specific example of this is given here. There are cases when unique constraints violation error is needed to be handled when save method\n+    of ``org.springframework.data.jpa.repository.JpaRepository`` interface provided by Spring Data JPA is called.\n+    In case of JPA, there is a mechanism of cache entity operations and SQL is executed when transactions are committed.\n+    Therefore, since SQL is not executed even if save method of JpaRepository is called, unique constraints violation error cannot be handled in logic.\n+    There is a method (flush method) to reflect cached operations as means to explicitly issue SQLs in JPA.\n+    saveAndFlush and flush methods are also provided in JpaRepository for the same purpose.\n+    Therefore, when unique constraints violation error needs to be handled using JpaRepository of Spring Data JPA,\n+    JPA dependent method (saveAndFlush or flush) must be called.\n+\n+ .. warning::\n+\n+    The most important purpose of creating Repository is not to exclude the persistence platform dependent logic from business logic.\n+    The most important purpose is to limit the implementation scope of business logic (Service) to the implementation of business rules. \n+    This is done by separating the operations to access business data in Repository. As an outcome of this, persistence platform dependent logic gets\n+    implemented in Repository instead of business logic (Service).\n+\n+\n+Creation of Repository\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+Repository must be created using the following policy only.\n+\n+\n+ .. list-table::\n+   :header-rows: 1\n+   :widths: 10 35 55\n+\n+   * - S.No.\n+     - Method\n+     - Supplementary\n+   * - | 1.\n+     - | Create Repository for the main Entity only.\n+     - | This means separate Repository for operations of related Entity is not required.\n+       | However, there are case when it is better to provide Repository for the related Entity in specific applications (for example, \n+       | application having high performance requirements etc).\n+   * - | 2.\n+     - | Place Repository interface and RepositoryImpl in the same package of domain layer.\n+     - | Repository interface belongs to domain layer and RepositoryImpl belongs to infrastructure layer. However,\n+       | Java package of RepositoryImpl can be same as the Repository interface of domain layer.\n+   * - | 3.\n+     - | Place DTO used in Repository in the same package as Repository interface.\n+     - | For example, DTO to store search criteria or summary DTO for that defines only a few items of Entity.\n+\n+\n+Example of creating Repository\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+| An example of creating Repository is explained here.\n+| An example of creating Repository of Entity class used in the explanation of \\ :ref:`domainlayer_entity_example`\\ is as follows.\n+\n+\n+Structure of Repository \n+\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n+Entity class used in the explanation of \\ :ref:`domainlayer_entity_example`\\ is used as an example, the resulting configuration is as follows:\n+\n+ .. figure:: images/domainlayer_repository_layout.png\n+   :alt: Example of repository layout\n+   :width: 100%\n+   :align: center\n+\n+\n+| Repository is created for the main Entity class.\n+| Refer to \\ :ref:`application-layering_project-structure`\\  for the recommended package structure.\n+\n+\n+.. _repository-interface-label:\n+\n+Definition of Repository interface\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+\n+Creation of Repository interface\n+\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n+\n+An example of creating Repository interface is introduced below.\n+\n+- :file:`SimpleCrudRepository.java`\n+\n+ | This interface provides only simple CRUD operations.\n+ | Method signature is created by referring to \\ ``CrudRepository``\\ interface and \\  ``PagingAndSortingRepository``\\ provided by Spring Data.\n+\n+ .. code-block:: java\n+\n+     public interface SimpleCrudRepository<T, ID extends Serializable> {\n+         // (1)\n+         T findOne(ID id);\n+         // (2)\n+         boolean exists(ID id);\n+         // (3)\n+         List<T> findAll();\n+         // (4)\n+         Page<T> findAll(Pageable pageable);\n+         // (5)\n+         long count();\n+         // (6)\n+         T save(T entity);\n+         // (7)\n+         void delete(T entity);\n+     }\n+\n+ .. list-table::\n+    :header-rows: 1\n+    :widths: 10 90\n+\n+    * - S.No.\n+      - Description\n+    * - | (1)\n+      - | Method to fetch the Entity object of specified ID.\n+    * - | (2)\n+      - | Method to determine if the Entity of specified ID exists or not.\n+    * - | (3)\n+      - | Method to retrieve the list of all Entities. In Spring Data, it was \\ ``java.util.Iterable``\\. Here as a sample, it is set to \\ ``java.util.List``\\ .\n+    * - | (4)\n+      - | Method to fetch collection of Entity objects corresponding to the specified pagination information (start position, record count, sort information).\n+        | ``Pageable`` and \\ ``Page``\\ are the interfaces provided by Spring Data.\n+    * - | (5)\n+      - | Method to fetch total number of Entity objects.\n+    * - | (6)\n+      - | Method to save (create, update) the specified Entity collection.\n+    * - | (7)\n+      - | Method to delete the specified Entity.\n+\n+\n+- :file:`TodoRepository.java`\n+\n+ An example of creating Repository of Todo Entity, which was created in tutorial, on the basis of \\ ``SimpleCrudRepository``\\  interface created above is shown below.\n+\n+ .. code-block:: java\n+\n+     // (1)\n+     public interface TodoRepository extends SimpleCrudRepository<Todo, String> {\n+         // (2)\n+         long countByFinished(boolean finished);\n+     }\n+\n+ .. list-table::\n+    :header-rows: 1\n+    :widths: 10 90\n+\n+    * - S.No.\n+      - Description\n+\n+    * - | (1)\n+      - | ToDoRepository interface is created by specifying Todo entity in the generic type parameter \"T\" and\n+        | String class in the generic type parameter \"ID\".\n+    * - | (2)\n+      - | Methods not provided by \\ ``SimpleCrudRepository``\\ interface are added in this interface.\n+        | In this case, \"Method for acquiring count of Todo entity objects for which specified tasks have been finished\" is added.\n+\n+\n+Method definition of Repository interface\n+\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n+\n+| It is recommended to have the same signature as \\ ``CrudRepository``\\ and \\ ``PagingAndSortingRepository``\\ provided by Spring Data for the methods performing general CRUD operations.\n+| However, in case of returning collection, (\\ ``java.util.Collection``\\ or \\``java.util.List``\\ ) interfaces which can be handled in a better way in logic are better than \\ ``java.lang.Iterable``\\.\n+| In real development environment, it is difficult to develop an application using only general CRUD operations. Hence additional methods are required.\n+| It is recommended to add the methods as per the following rules.\n+\n+ .. list-table::\n+    :header-rows: 1\n+    :widths: 10 20 70\n+\n+    * - S.No.\n+      - Types of methods\n+      - Rules\n+    * - 1.\n+      - Method for searching a single record\n+      - #. Method name beginning with \\ **findOneBy**\\ to indicate that this method fetches a single record that matches with the condition.\n+        #. In the method name after \"findOneBy\", physical or logical name of the field used as search condition must be specified. Hence, the method name must\n+        #  be such that it becomes possible to estimate \"the kind of entity that can be fetched using this method\".\n+        #. There must be an argument for each search condition. However, when there are many conditions, DTO containing all search conditions can be provided.\n+        #. Return value must be Entity class.\n+    * - 2.\n+      - Method for searching multiple records\n+      - #. Method name beginning with \\ **findOneBy**\\ to indicate that this method fetches all the records that matches with the condition.\n+        #. In the method name after \"findAllBy\", physical or logical name of the field used as search condition must be specified. Hence, the method name must\n+        #  be such that it becomes possible to estimate \"the kind of entity that can be fetched using this method\".\n+        #. There must be an argument for each search condition. However, when there are many conditions, DTO containing all search conditions can be provided.\n+        #. Return value must be collection of Entity class.\n+    * - 3.\n+      - Method for searching multiple records with pagination\n+      - #. Method name beginning with \\ **findPageBy**\\ to indicate that this method fetches pages that matches with the condition.\n+        #. In the method name after \"findPageBy\", physical or logical name of the field used as search condition must be specified. Hence, the method name must\n+        #  be such that it becomes possible to estimate \"the kind of entity that can be fetched using this method\".\n+        #. There must be an argument for each search condition. However, when there are many conditions, DTO containing all search conditions can be provided.\n+        #  ``Pageable`` provided by Spring Data should be the interface for pagination information (start position, record count, sort information).\n+        #. Return value should be ``Page`` interface provided by Spring Data.\n+    * - 4.\n+      - Count related method\n+      - #. Method name beginning with **countBy** to indicate that this method fetches count of Entities which matches with the condition.\n+        #. Return value must be long type.\n+        #. In the method name after \"countBy\", physical or logical name of the field used as search condition must be specified. Hence, the method name must\n+        #  be such that it becomes possible to estimate \"the kind of entity that can be fetched using this method\".\n+        #. There must be an argument for each search condition. However, when there are many conditions, DTO containing all search conditions can be provided.\n+    * - 5.\n+      - Method for existence check\n+      - #. Method name beginning with **existsBy** to indicate that this method checks the existence of Entity which matches with the condition.\n+        #. In the method name after \"existsBy\"physical or logical name of the field used as search condition must be specified. Hence, the method name must\n+        #  be such that it becomes possible to estimate \"the kind of entity that can be fetched using this method\".\n+        #. There must be an argument for each search condition. However, when there are many conditions, DTO containing all search conditions can be provided.\n+        #. Return value must be boolean type.\n+\n+ .. note::\n+\n+     In case of methods related to update processing, it is recommended to construct methods in the same way as shown above.\n+     \"find\" in the method name above can be replaced by \"update\" or \"delete\".\n+\n+\n+- :file:`Todo.java` (Entity)\n+\n+ .. code-block:: java\n+\n+     public class Todo implements Serializable {\n+         private String todoId;\n+         private String todoTitle;\n+         private boolean finished;\n+         private Date createdAt;\n+         // ...\n+      }\n+\n+|\n+\n+- :file:`TodoRepository.java`\n+\n+ .. code-block:: java\n+\n+      public interface TodoRepository extends SimpleCrudRepository<Todo, String> {\n+          // (1)\n+          Todo findOneByTodoTitle(String todoTitle);\n+          // (2)\n+          List<Todo> findAllByUnfinished();\n+          // (3)\n+          Page<Todo> findPageByUnfinished();\n+          // (4)\n+          long countByExpired(int validDays);\n+          // (5)\n+          boolean existsByCreateAt(Date date);\n+      }\n+\n+ .. list-table::\n+    :header-rows: 1\n+    :widths: 10 90\n+\n+    * - S.No.\n+      - Description\n+    * - | (1)\n+      - | Example of method that fetches TODO objects whose title matches with specified value (TODO in which todoTitle=[argument value]).\n+        | Physical name(todoTitle) of condition field is specified after findOneBy.\n+    * - | (2)\n+      - | Example of method that fetches unfinished TODO objects (TODO objects where finished=false).\n+        | Logical condition name is specified after findAllBy.\n+    * - | (3)\n+      - | Example of method that fetches pages of unfinished TODOs (TODO objects where finished=false).\n+        | Logical condition name is specified after findPageBy.\n+    * - | (4)\n+      - | Example of method that fetches count of TODO objects for which the finish deadline has already passed (TODO for which createdAt < sysdate - [finish deadline in days] && finished=false).\n+        | Logical condition name is specified after countBy.\n+    * - | (5)\n+      - | Example of method that checks whether a TODO is created on a specific date (createdAt=specified date).\n+        | Physical name (createdAt) is specified after existsBy.\n+\n+\n+Creation of RepositoryImpl\n+\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n+Refer to \\ :doc:`InfrastructureLayer`\\ for the implementation of RepositoryImpl.\n+\n+\n+.. _service-label:\n+\n+Implementation of Service\n+--------------------------------------------------------------------------------\n+\n+Roles of Service\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+Service plays the following 2 roles.\n+\n+1. | **Provides business logic to Controller.**\n+   | Business logic consists of create, update, consistency check etc of business data as well as all the processes related to business logic.\n+   | Create and update process of business data should be delegated to Repository(or O/R Mapper) and \\ ** service should be limited to implementation of business rules.**\\\n+\n+ .. note:: **Regarding distribution of logic between Controller and Service**\n+\n+    In this guideline. the logic to be implemented by Controller and Service should be as per the rules given below.\n+\n+    1. For the data requested from the client, single item check and correlated item check is to be performed in Controller (Bean Validation or Spring Validator).\n+\n+    2. Conversion processes (Bean conversion, Type conversion and Format conversion) for the data to be passed to Service, must be performed in Controller instead of Service.\n+\n+    3. \\ **Business rules should be implemented in Service. **\\ Access to business data is to be delegated to Repository or O/R Mapper.","path":"source_en/ImplementationAtEachLayer/DomainLayer.rst","position":670,"original_position":670,"commit_id":"db5b36b26b1da9302fbc90fef8511e06d41b535f","original_commit_id":"db5b36b26b1da9302fbc90fef8511e06d41b535f","user":{"login":"kazuki43zoo","id":5616270,"avatar_url":"https://avatars.githubusercontent.com/u/5616270?","gravatar_id":"8bd20986e95a61ff08ba4a12456f1b08","url":"https://api.github.com/users/kazuki43zoo","html_url":"https://github.com/kazuki43zoo","followers_url":"https://api.github.com/users/kazuki43zoo/followers","following_url":"https://api.github.com/users/kazuki43zoo/following{/other_user}","gists_url":"https://api.github.com/users/kazuki43zoo/gists{/gist_id}","starred_url":"https://api.github.com/users/kazuki43zoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kazuki43zoo/subscriptions","organizations_url":"https://api.github.com/users/kazuki43zoo/orgs","repos_url":"https://api.github.com/users/kazuki43zoo/repos","events_url":"https://api.github.com/users/kazuki43zoo/events{/privacy}","received_events_url":"https://api.github.com/users/kazuki43zoo/received_events","type":"User","site_admin":false},"body":"mistake syntax of bold.","created_at":"2014-04-06T05:56:44Z","updated_at":"2014-04-06T05:56:44Z","html_url":"https://github.com/terasolunaorg/guideline/pull/132#discussion_r11324686","pull_request_url":"https://api.github.com/repos/terasolunaorg/guideline/pulls/132","_links":{"self":{"href":"https://api.github.com/repos/terasolunaorg/guideline/pulls/comments/11324686"},"html":{"href":"https://github.com/terasolunaorg/guideline/pull/132#discussion_r11324686"},"pull_request":{"href":"https://api.github.com/repos/terasolunaorg/guideline/pulls/132"}}}}