#84 Documented the Layers example

This commit is contained in:
Ilkka Seppala 2015-08-15 19:27:53 +03:00
parent 9aa831d688
commit db9a00ebb1
15 changed files with 158 additions and 0 deletions

View File

@ -2,10 +2,67 @@ package com.iluwatar.layers;
import java.util.Arrays;
/**
*
* <p>
* Multilayered architecture is an architectural style where software responsibilities are
* divided among the different layers of the application.
* </p>
*
* <p>
* This example demonstrates a traditional 3-layer architecture consisting of data access
* layer, business layer and presentation layer.
* </p>
*
* <p>
* The data access layer is formed of Spring Data repositories <code>CakeDao</code>, <code>CakeToppingDao</code> and
* <code>CakeLayerDao</code>. The repositories can be used for CRUD operations on cakes, cake toppings
* and cake layers respectively.
* </p>
*
* <p>
* The business layer is built on top of the data access layer. <code>CakeBakingService</code> offers
* methods to retrieve available cake toppings and cake layers and baked cakes. Also the
* service is used to create new cakes out of cake toppings and cake layers.
* </p>
*
* <p>
* The presentation layer is built on the business layer and in this example it simply lists
* the cakes that have been baked.
* </p>
*
* <p>
* We have applied so called strict layering which means that the layers can only access
* the classes directly beneath them. This leads the solution to create an additional set of
* DTOs (<code>CakeInfo</code>, <code>CakeToppingInfo</code>, <code>CakeLayerInfo</code>)
* to translate data between layers. In other words, <code>CakeBakingService</code> cannot
* return entities (<code>Cake</code>, <code>CakeTopping</code>, <code>CakeLayer</code>)
* directly since these reside on data access layer but instead translates these into business
* layer DTOs (<code>CakeInfo</code>, <code>CakeToppingInfo</code>, <code>CakeLayerInfo</code>)
* and returns them instead. This way the presentation layer does not have any knowledge of
* other layers than the business layer and thus is not affected by changes to them.
* </p>
*
* @see Cake
* @see CakeTopping
* @see CakeLayer
* @see CakeDao
* @see CakeToppingDao
* @see CakeLayerDao
* @see CakeBakingService
* @see CakeInfo
* @see CakeToppingInfo
* @see CakeLayerInfo
*
*/
public class App {
private static CakeBakingService cakeBakingService = new CakeBakingServiceImpl();
/**
* Application entry point
* @param args Command line parameters
*/
public static void main(String[] args) {
// initialize example data
@ -16,6 +73,10 @@ public class App {
cakeView.render();
}
/**
* Initializes the example data
* @param cakeBakingService
*/
private static void initializeData(CakeBakingService cakeBakingService) {
cakeBakingService.saveNewLayer(new CakeLayerInfo("chocolate", 1200));
cakeBakingService.saveNewLayer(new CakeLayerInfo("banana", 900));

View File

@ -11,6 +11,11 @@ import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
/**
*
* Cake entity
*
*/
@Entity
public class Cake {

View File

@ -1,7 +1,14 @@
package com.iluwatar.layers;
/**
*
* Custom exception used in cake baking
*
*/
public class CakeBakingException extends Exception {
private static final long serialVersionUID = 1L;
public CakeBakingException() {
}

View File

@ -2,17 +2,47 @@ package com.iluwatar.layers;
import java.util.List;
/**
*
* Service for cake baking operations
*
*/
public interface CakeBakingService {
/**
* Bakes new cake according to parameters
* @param cakeInfo
* @throws CakeBakingException
*/
void bakeNewCake(CakeInfo cakeInfo) throws CakeBakingException;
/**
* Get all cakes
* @return
*/
List<CakeInfo> getAllCakes();
/**
* Store new cake topping
* @param toppingInfo
*/
void saveNewTopping(CakeToppingInfo toppingInfo);
/**
* Get available cake toppings
* @return
*/
List<CakeToppingInfo> getAvailableToppings();
/**
* Add new cake layer
* @param layerInfo
*/
void saveNewLayer(CakeLayerInfo layerInfo);
/**
* Get available cake layers
* @return
*/
List<CakeLayerInfo> getAvailableLayers();
}

View File

@ -13,6 +13,11 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
*
* Implementation of CakeBakingService
*
*/
@Service
@Transactional
public class CakeBakingServiceImpl implements CakeBakingService {

View File

@ -3,6 +3,11 @@ package com.iluwatar.layers;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
/**
*
* CRUD repository for cakes
*
*/
@Repository
public interface CakeDao extends CrudRepository<Cake, Long> {

View File

@ -3,6 +3,11 @@ package com.iluwatar.layers;
import java.util.List;
import java.util.Optional;
/**
*
* DTO for cakes
*
*/
public class CakeInfo {
public final Optional<Long> id;

View File

@ -6,6 +6,11 @@ import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
/**
*
* CakeLayer entity
*
*/
@Entity
public class CakeLayer {

View File

@ -3,6 +3,11 @@ package com.iluwatar.layers;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
/**
*
* CRUD repository for cake layers
*
*/
@Repository
public interface CakeLayerDao extends CrudRepository<CakeLayer, Long> {

View File

@ -2,6 +2,11 @@ package com.iluwatar.layers;
import java.util.Optional;
/**
*
* DTO for cake layers
*
*/
public class CakeLayerInfo {
public final Optional<Long> id;

View File

@ -6,6 +6,11 @@ import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
/**
*
* CakeTopping entity
*
*/
@Entity
public class CakeTopping {

View File

@ -3,6 +3,11 @@ package com.iluwatar.layers;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
/**
*
* CRUD repository cake toppings
*
*/
@Repository
public interface CakeToppingDao extends CrudRepository<CakeTopping, Long> {

View File

@ -2,6 +2,11 @@ package com.iluwatar.layers;
import java.util.Optional;
/**
*
* DTO for cake toppings
*
*/
public class CakeToppingInfo {
public final Optional<Long> id;

View File

@ -1,5 +1,10 @@
package com.iluwatar.layers;
/**
*
* View implementation for displaying cakes
*
*/
public class CakeViewImpl implements View {
private CakeBakingService cakeBakingService;

View File

@ -1,5 +1,10 @@
package com.iluwatar.layers;
/**
*
* View interface
*
*/
public interface View {
void render();