#84 Documented the Layers example
This commit is contained in:
parent
9aa831d688
commit
db9a00ebb1
@ -2,10 +2,67 @@ package com.iluwatar.layers;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
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 {
|
public class App {
|
||||||
|
|
||||||
private static CakeBakingService cakeBakingService = new CakeBakingServiceImpl();
|
private static CakeBakingService cakeBakingService = new CakeBakingServiceImpl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Application entry point
|
||||||
|
* @param args Command line parameters
|
||||||
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
// initialize example data
|
// initialize example data
|
||||||
@ -16,6 +73,10 @@ public class App {
|
|||||||
cakeView.render();
|
cakeView.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the example data
|
||||||
|
* @param cakeBakingService
|
||||||
|
*/
|
||||||
private static void initializeData(CakeBakingService cakeBakingService) {
|
private static void initializeData(CakeBakingService cakeBakingService) {
|
||||||
cakeBakingService.saveNewLayer(new CakeLayerInfo("chocolate", 1200));
|
cakeBakingService.saveNewLayer(new CakeLayerInfo("chocolate", 1200));
|
||||||
cakeBakingService.saveNewLayer(new CakeLayerInfo("banana", 900));
|
cakeBakingService.saveNewLayer(new CakeLayerInfo("banana", 900));
|
||||||
|
@ -11,6 +11,11 @@ import javax.persistence.Id;
|
|||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Cake entity
|
||||||
|
*
|
||||||
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
public class Cake {
|
public class Cake {
|
||||||
|
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
package com.iluwatar.layers;
|
package com.iluwatar.layers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Custom exception used in cake baking
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class CakeBakingException extends Exception {
|
public class CakeBakingException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public CakeBakingException() {
|
public CakeBakingException() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,17 +2,47 @@ package com.iluwatar.layers;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Service for cake baking operations
|
||||||
|
*
|
||||||
|
*/
|
||||||
public interface CakeBakingService {
|
public interface CakeBakingService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bakes new cake according to parameters
|
||||||
|
* @param cakeInfo
|
||||||
|
* @throws CakeBakingException
|
||||||
|
*/
|
||||||
void bakeNewCake(CakeInfo cakeInfo) throws CakeBakingException;
|
void bakeNewCake(CakeInfo cakeInfo) throws CakeBakingException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all cakes
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
List<CakeInfo> getAllCakes();
|
List<CakeInfo> getAllCakes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store new cake topping
|
||||||
|
* @param toppingInfo
|
||||||
|
*/
|
||||||
void saveNewTopping(CakeToppingInfo toppingInfo);
|
void saveNewTopping(CakeToppingInfo toppingInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get available cake toppings
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
List<CakeToppingInfo> getAvailableToppings();
|
List<CakeToppingInfo> getAvailableToppings();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new cake layer
|
||||||
|
* @param layerInfo
|
||||||
|
*/
|
||||||
void saveNewLayer(CakeLayerInfo layerInfo);
|
void saveNewLayer(CakeLayerInfo layerInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get available cake layers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
List<CakeLayerInfo> getAvailableLayers();
|
List<CakeLayerInfo> getAvailableLayers();
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,11 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Implementation of CakeBakingService
|
||||||
|
*
|
||||||
|
*/
|
||||||
@Service
|
@Service
|
||||||
@Transactional
|
@Transactional
|
||||||
public class CakeBakingServiceImpl implements CakeBakingService {
|
public class CakeBakingServiceImpl implements CakeBakingService {
|
||||||
|
@ -3,6 +3,11 @@ package com.iluwatar.layers;
|
|||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* CRUD repository for cakes
|
||||||
|
*
|
||||||
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
public interface CakeDao extends CrudRepository<Cake, Long> {
|
public interface CakeDao extends CrudRepository<Cake, Long> {
|
||||||
|
|
||||||
|
@ -3,6 +3,11 @@ package com.iluwatar.layers;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* DTO for cakes
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class CakeInfo {
|
public class CakeInfo {
|
||||||
|
|
||||||
public final Optional<Long> id;
|
public final Optional<Long> id;
|
||||||
|
@ -6,6 +6,11 @@ import javax.persistence.GeneratedValue;
|
|||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* CakeLayer entity
|
||||||
|
*
|
||||||
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
public class CakeLayer {
|
public class CakeLayer {
|
||||||
|
|
||||||
|
@ -3,6 +3,11 @@ package com.iluwatar.layers;
|
|||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* CRUD repository for cake layers
|
||||||
|
*
|
||||||
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
public interface CakeLayerDao extends CrudRepository<CakeLayer, Long> {
|
public interface CakeLayerDao extends CrudRepository<CakeLayer, Long> {
|
||||||
|
|
||||||
|
@ -2,6 +2,11 @@ package com.iluwatar.layers;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* DTO for cake layers
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class CakeLayerInfo {
|
public class CakeLayerInfo {
|
||||||
|
|
||||||
public final Optional<Long> id;
|
public final Optional<Long> id;
|
||||||
|
@ -6,6 +6,11 @@ import javax.persistence.GeneratedValue;
|
|||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* CakeTopping entity
|
||||||
|
*
|
||||||
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
public class CakeTopping {
|
public class CakeTopping {
|
||||||
|
|
||||||
|
@ -3,6 +3,11 @@ package com.iluwatar.layers;
|
|||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* CRUD repository cake toppings
|
||||||
|
*
|
||||||
|
*/
|
||||||
@Repository
|
@Repository
|
||||||
public interface CakeToppingDao extends CrudRepository<CakeTopping, Long> {
|
public interface CakeToppingDao extends CrudRepository<CakeTopping, Long> {
|
||||||
|
|
||||||
|
@ -2,6 +2,11 @@ package com.iluwatar.layers;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* DTO for cake toppings
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class CakeToppingInfo {
|
public class CakeToppingInfo {
|
||||||
|
|
||||||
public final Optional<Long> id;
|
public final Optional<Long> id;
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
package com.iluwatar.layers;
|
package com.iluwatar.layers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* View implementation for displaying cakes
|
||||||
|
*
|
||||||
|
*/
|
||||||
public class CakeViewImpl implements View {
|
public class CakeViewImpl implements View {
|
||||||
|
|
||||||
private CakeBakingService cakeBakingService;
|
private CakeBakingService cakeBakingService;
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
package com.iluwatar.layers;
|
package com.iluwatar.layers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* View interface
|
||||||
|
*
|
||||||
|
*/
|
||||||
public interface View {
|
public interface View {
|
||||||
|
|
||||||
void render();
|
void render();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user