Compare commits
3 Commits
master
...
business-d
Author | SHA1 | Date | |
---|---|---|---|
|
a163a46e03 | ||
|
964f2c56ad | ||
|
e0f1376bd0 |
@ -9,21 +9,156 @@ tags:
|
||||
---
|
||||
|
||||
## Intent
|
||||
|
||||
The Business Delegate pattern adds an abstraction layer between
|
||||
presentation and business tiers. By using the pattern we gain loose coupling
|
||||
between the tiers and encapsulate knowledge about how to locate, connect to,
|
||||
and interact with the business objects that make up the application.
|
||||
|
||||
## Explanation
|
||||
|
||||
Real world example
|
||||
|
||||
> A mobile phone application promises to stream any movie in existence to your phone. It captures
|
||||
> the user's search string and passes this on to the business delegate. The business delegate
|
||||
> selects the most suitable video streaming service and plays the video from there.
|
||||
|
||||
In Plain Words
|
||||
|
||||
> Business delegate adds an abstraction layer between the presentation and business tiers.
|
||||
|
||||
Wikipedia says
|
||||
|
||||
> Business delegate is a Java EE design pattern. This pattern is directing to reduce the coupling
|
||||
> in between business services and the connected presentation tier, and to hide the implementation
|
||||
> details of services (including lookup and accessibility of EJB architecture). Business delegates
|
||||
> acts as an adaptor to invoke business objects from the presentation tier.
|
||||
|
||||
**Programmatic Example**
|
||||
|
||||
First, we have an abstraction for video streaming services and a couple of implementations.
|
||||
|
||||
```java
|
||||
public interface VideoStreamingService {
|
||||
void doProcessing();
|
||||
}
|
||||
|
||||
@Slf4j
|
||||
public class NetflixService implements VideoStreamingService {
|
||||
@Override
|
||||
public void doProcessing() {
|
||||
LOGGER.info("NetflixService is now processing");
|
||||
}
|
||||
}
|
||||
|
||||
@Slf4j
|
||||
public class YouTubeService implements VideoStreamingService {
|
||||
@Override
|
||||
public void doProcessing() {
|
||||
LOGGER.info("YouTubeService is now processing");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then we have a lookup service that decides which video streaming service is used.
|
||||
|
||||
```java
|
||||
@Setter
|
||||
public class BusinessLookup {
|
||||
|
||||
private NetflixService netflixService;
|
||||
private YouTubeService youTubeService;
|
||||
|
||||
public VideoStreamingService getBusinessService(String movie) {
|
||||
if (movie.toLowerCase(Locale.ROOT).contains("die hard")) {
|
||||
return netflixService;
|
||||
} else {
|
||||
return youTubeService;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The business delegate uses a business lookup to route movie playback requests to a suitable
|
||||
video streaming service.
|
||||
|
||||
```java
|
||||
@Setter
|
||||
public class BusinessDelegate {
|
||||
|
||||
private BusinessLookup lookupService;
|
||||
|
||||
public void playbackMovie(String movie) {
|
||||
VideoStreamingService videoStreamingService = lookupService.getBusinessService(movie);
|
||||
videoStreamingService.doProcessing();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The mobile client utilizes business delegate to call the business tier.
|
||||
|
||||
```java
|
||||
public class MobileClient {
|
||||
|
||||
private final BusinessDelegate businessDelegate;
|
||||
|
||||
public MobileClient(BusinessDelegate businessDelegate) {
|
||||
this.businessDelegate = businessDelegate;
|
||||
}
|
||||
|
||||
public void playbackMovie(String movie) {
|
||||
businessDelegate.playbackMovie(movie);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Finally, we can show the full example in action.
|
||||
|
||||
```java
|
||||
public static void main(String[] args) {
|
||||
|
||||
// prepare the objects
|
||||
var businessDelegate = new BusinessDelegate();
|
||||
var businessLookup = new BusinessLookup();
|
||||
businessLookup.setNetflixService(new NetflixService());
|
||||
businessLookup.setYouTubeService(new YouTubeService());
|
||||
businessDelegate.setLookupService(businessLookup);
|
||||
|
||||
// create the client and use the business delegate
|
||||
var client = new MobileClient(businessDelegate);
|
||||
client.playbackMovie("Die Hard 2");
|
||||
client.playbackMovie("Maradona: The Greatest Ever");
|
||||
}
|
||||
```
|
||||
|
||||
Here is the console output.
|
||||
|
||||
```
|
||||
21:15:33.790 [main] INFO com.iluwatar.business.delegate.NetflixService - NetflixService is now processing
|
||||
21:15:33.794 [main] INFO com.iluwatar.business.delegate.YouTubeService - YouTubeService is now processing
|
||||
```
|
||||
|
||||
## Class diagram
|
||||

|
||||
|
||||

|
||||
|
||||
## Related patterns
|
||||
|
||||
* [Service locator pattern](https://java-design-patterns.com/patterns/service-locator/)
|
||||
|
||||
## Applicability
|
||||
|
||||
Use the Business Delegate pattern when
|
||||
|
||||
* you want loose coupling between presentation and business tiers
|
||||
* you want to orchestrate calls to multiple business services
|
||||
* you want to encapsulate service lookups and service calls
|
||||
* You want loose coupling between presentation and business tiers
|
||||
* You want to orchestrate calls to multiple business services
|
||||
* You want to encapsulate service lookups and service calls
|
||||
|
||||
## Tutorials
|
||||
|
||||
* [Business Delegate Pattern at TutorialsPoint](https://www.tutorialspoint.com/design_pattern/business_delegate_pattern.htm)
|
||||
|
||||
## Credits
|
||||
|
||||
* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=48d37c67fb3d845b802fa9b619ad8f31)
|
||||
* [Core J2EE Patterns: Best Practices and Design Strategies](https://www.amazon.com/gp/product/0130648841/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=javadesignpat-20&creative=9325&linkCode=as2&creativeASIN=0130648841&linkId=a0100de2b28c71ede8db1757fb2b5947)
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 24 KiB |
@ -1,136 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
|
||||
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
|
||||
<class id="1" language="java" name="com.iluwatar.business.delegate.BusinessDelegate" project="business-delegate"
|
||||
file="/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessDelegate.java" binary="false"
|
||||
corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="272" y="219"/>
|
||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||
</display>
|
||||
</class>
|
||||
<class id="2" language="java" name="com.iluwatar.business.delegate.Client" project="business-delegate"
|
||||
file="/business-delegate/src/main/java/com/iluwatar/business/delegate/Client.java" binary="false"
|
||||
corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="272" y="64"/>
|
||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||
</display>
|
||||
</class>
|
||||
<enumeration id="3" language="java" name="com.iluwatar.business.delegate.ServiceType" project="business-delegate"
|
||||
file="/business-delegate/src/main/java/com/iluwatar/business/delegate/ServiceType.java" binary="false"
|
||||
corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="89" y="383"/>
|
||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||
</display>
|
||||
</enumeration>
|
||||
<interface id="4" language="java" name="com.iluwatar.business.delegate.BusinessService" project="business-delegate"
|
||||
file="/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessService.java" binary="false"
|
||||
corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="630" y="365"/>
|
||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||
</display>
|
||||
</interface>
|
||||
<class id="5" language="java" name="com.iluwatar.business.delegate.JmsService" project="business-delegate"
|
||||
file="/business-delegate/src/main/java/com/iluwatar/business/delegate/JmsService.java" binary="false"
|
||||
corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="489" y="210"/>
|
||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||
</display>
|
||||
</class>
|
||||
<class id="6" language="java" name="com.iluwatar.business.delegate.BusinessLookup" project="business-delegate"
|
||||
file="/business-delegate/src/main/java/com/iluwatar/business/delegate/BusinessLookup.java" binary="false"
|
||||
corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="360" y="399"/>
|
||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||
</display>
|
||||
</class>
|
||||
<class id="7" language="java" name="com.iluwatar.business.delegate.EjbService" project="business-delegate"
|
||||
file="/business-delegate/src/main/java/com/iluwatar/business/delegate/EjbService.java" binary="false"
|
||||
corner="BOTTOM_RIGHT">
|
||||
<position height="-1" width="-1" x="668" y="210"/>
|
||||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||
</display>
|
||||
</class>
|
||||
<realization id="8">
|
||||
<end type="SOURCE" refId="7"/>
|
||||
<end type="TARGET" refId="4"/>
|
||||
</realization>
|
||||
<association id="9">
|
||||
<end type="SOURCE" refId="1" navigable="false">
|
||||
<attribute id="10" name="lookupService">
|
||||
<position height="0" width="0" x="0" y="0"/>
|
||||
</attribute>
|
||||
<multiplicity id="11" minimum="0" maximum="1">
|
||||
<position height="0" width="0" x="0" y="0"/>
|
||||
</multiplicity>
|
||||
</end>
|
||||
<end type="TARGET" refId="6" navigable="true"/>
|
||||
<display labels="true" multiplicity="true"/>
|
||||
</association>
|
||||
<association id="12">
|
||||
<end type="SOURCE" refId="1" navigable="false">
|
||||
<attribute id="13" name="serviceType">
|
||||
<position height="0" width="0" x="0" y="0"/>
|
||||
</attribute>
|
||||
<multiplicity id="14" minimum="0" maximum="1">
|
||||
<position height="0" width="0" x="0" y="0"/>
|
||||
</multiplicity>
|
||||
</end>
|
||||
<end type="TARGET" refId="3" navigable="true"/>
|
||||
<display labels="true" multiplicity="true"/>
|
||||
</association>
|
||||
<realization id="15">
|
||||
<end type="SOURCE" refId="5"/>
|
||||
<end type="TARGET" refId="4"/>
|
||||
</realization>
|
||||
<association id="16">
|
||||
<end type="SOURCE" refId="2" navigable="false">
|
||||
<attribute id="17" name="businessDelegate">
|
||||
<position height="0" width="0" x="0" y="0"/>
|
||||
</attribute>
|
||||
<multiplicity id="18" minimum="0" maximum="1">
|
||||
<position height="0" width="0" x="0" y="0"/>
|
||||
</multiplicity>
|
||||
</end>
|
||||
<end type="TARGET" refId="1" navigable="true"/>
|
||||
<display labels="true" multiplicity="true"/>
|
||||
</association>
|
||||
<association id="19">
|
||||
<end type="SOURCE" refId="1" navigable="false">
|
||||
<attribute id="20" name="businessService">
|
||||
<position height="0" width="0" x="0" y="0"/>
|
||||
</attribute>
|
||||
<multiplicity id="21" minimum="0" maximum="1">
|
||||
<position height="0" width="0" x="0" y="0"/>
|
||||
</multiplicity>
|
||||
</end>
|
||||
<end type="TARGET" refId="4" navigable="true"/>
|
||||
<display labels="true" multiplicity="true"/>
|
||||
</association>
|
||||
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
|
||||
sort-features="false" accessors="true" visibility="true">
|
||||
<attributes public="true" package="true" protected="true" private="true" static="true"/>
|
||||
<operations public="true" package="true" protected="true" private="true" static="true"/>
|
||||
</classifier-display>
|
||||
<association-display labels="true" multiplicity="true"/>
|
||||
</class-diagram>
|
BIN
business-delegate/etc/business-delegate.urm.png
Normal file
BIN
business-delegate/etc/business-delegate.urm.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
@ -5,53 +5,42 @@ package com.iluwatar.business.delegate {
|
||||
+ main(args : String[]) {static}
|
||||
}
|
||||
class BusinessDelegate {
|
||||
- businessService : BusinessService
|
||||
- lookupService : BusinessLookup
|
||||
- serviceType : ServiceType
|
||||
+ BusinessDelegate()
|
||||
+ doTask()
|
||||
+ setLookupService(businessLookup : BusinessLookup)
|
||||
+ setServiceType(serviceType : ServiceType)
|
||||
+ playbackMovie(movie : String)
|
||||
+ setLookupService(lookupService : BusinessLookup)
|
||||
}
|
||||
class BusinessLookup {
|
||||
- ejbService : EjbService
|
||||
- jmsService : JmsService
|
||||
- netflixService : NetflixService
|
||||
- youTubeService : YouTubeService
|
||||
+ BusinessLookup()
|
||||
+ getBusinessService(serviceType : ServiceType) : BusinessService
|
||||
+ setEjbService(ejbService : EjbService)
|
||||
+ setJmsService(jmsService : JmsService)
|
||||
+ getBusinessService(movie : String) : VideoStreamingService
|
||||
+ setNetflixService(netflixService : NetflixService)
|
||||
+ setYouTubeService(youTubeService : YouTubeService)
|
||||
}
|
||||
interface BusinessService {
|
||||
class MobileClient {
|
||||
- businessDelegate : BusinessDelegate
|
||||
+ MobileClient(businessDelegate : BusinessDelegate)
|
||||
+ playbackMovie(movie : String)
|
||||
}
|
||||
class NetflixService {
|
||||
- LOGGER : Logger {static}
|
||||
+ NetflixService()
|
||||
+ doProcessing()
|
||||
}
|
||||
interface VideoStreamingService {
|
||||
+ doProcessing() {abstract}
|
||||
}
|
||||
class Client {
|
||||
- businessDelegate : BusinessDelegate
|
||||
+ Client(businessDelegate : BusinessDelegate)
|
||||
+ doTask()
|
||||
}
|
||||
class EjbService {
|
||||
class YouTubeService {
|
||||
- LOGGER : Logger {static}
|
||||
+ EjbService()
|
||||
+ YouTubeService()
|
||||
+ doProcessing()
|
||||
}
|
||||
class JmsService {
|
||||
- LOGGER : Logger {static}
|
||||
+ JmsService()
|
||||
+ doProcessing()
|
||||
}
|
||||
enum ServiceType {
|
||||
+ EJB {static}
|
||||
+ JMS {static}
|
||||
+ valueOf(name : String) : ServiceType {static}
|
||||
+ values() : ServiceType[] {static}
|
||||
}
|
||||
}
|
||||
BusinessLookup --> "-ejbService" EjbService
|
||||
BusinessDelegate --> "-serviceType" ServiceType
|
||||
Client --> "-businessDelegate" BusinessDelegate
|
||||
BusinessDelegate --> "-businessService" BusinessService
|
||||
BusinessLookup --> "-netflixService" NetflixService
|
||||
BusinessLookup --> "-youTubeService" YouTubeService
|
||||
MobileClient --> "-businessDelegate" BusinessDelegate
|
||||
BusinessDelegate --> "-lookupService" BusinessLookup
|
||||
BusinessLookup --> "-jmsService" JmsService
|
||||
EjbService ..|> BusinessService
|
||||
JmsService ..|> BusinessService
|
||||
NetflixService ..|> VideoStreamingService
|
||||
YouTubeService ..|> VideoStreamingService
|
||||
@enduml
|
@ -33,9 +33,9 @@ package com.iluwatar.business.delegate;
|
||||
* retrieved through service lookups. The Business Delegate itself may contain business logic too
|
||||
* potentially tying together multiple service calls, exception handling, retrying etc.
|
||||
*
|
||||
* <p>In this example the client ({@link Client}) utilizes a business delegate (
|
||||
* {@link BusinessDelegate}) to execute a task. The Business Delegate then selects the appropriate
|
||||
* service and makes the service call.
|
||||
* <p>In this example the client ({@link MobileClient}) utilizes a business delegate (
|
||||
* {@link BusinessDelegate}) to search for movies in video streaming services. The Business Delegate
|
||||
* then selects the appropriate service and makes the service call.
|
||||
*/
|
||||
public class App {
|
||||
|
||||
@ -46,18 +46,16 @@ public class App {
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
// prepare the objects
|
||||
var businessDelegate = new BusinessDelegate();
|
||||
var businessLookup = new BusinessLookup();
|
||||
businessLookup.setEjbService(new EjbService());
|
||||
businessLookup.setJmsService(new JmsService());
|
||||
|
||||
businessLookup.setNetflixService(new NetflixService());
|
||||
businessLookup.setYouTubeService(new YouTubeService());
|
||||
businessDelegate.setLookupService(businessLookup);
|
||||
businessDelegate.setServiceType(ServiceType.EJB);
|
||||
|
||||
var client = new Client(businessDelegate);
|
||||
client.doTask();
|
||||
|
||||
businessDelegate.setServiceType(ServiceType.JMS);
|
||||
client.doTask();
|
||||
// create the client and use the business delegate
|
||||
var client = new MobileClient(businessDelegate);
|
||||
client.playbackMovie("Die Hard 2");
|
||||
client.playbackMovie("Maradona: The Greatest Ever");
|
||||
}
|
||||
}
|
||||
|
@ -23,24 +23,18 @@
|
||||
|
||||
package com.iluwatar.business.delegate;
|
||||
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* BusinessDelegate separates the presentation and business tiers.
|
||||
*/
|
||||
@Setter
|
||||
public class BusinessDelegate {
|
||||
|
||||
private BusinessLookup lookupService;
|
||||
private ServiceType serviceType;
|
||||
|
||||
public void setLookupService(BusinessLookup businessLookup) {
|
||||
this.lookupService = businessLookup;
|
||||
}
|
||||
|
||||
public void setServiceType(ServiceType serviceType) {
|
||||
this.serviceType = serviceType;
|
||||
}
|
||||
|
||||
public void doTask() {
|
||||
BusinessService businessService = lookupService.getBusinessService(serviceType);
|
||||
businessService.doProcessing();
|
||||
public void playbackMovie(String movie) {
|
||||
VideoStreamingService videoStreamingService = lookupService.getBusinessService(movie);
|
||||
videoStreamingService.doProcessing();
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
package com.iluwatar.business.delegate;
|
||||
|
||||
import java.util.Locale;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
@ -31,21 +32,21 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class BusinessLookup {
|
||||
|
||||
private EjbService ejbService;
|
||||
private NetflixService netflixService;
|
||||
|
||||
private JmsService jmsService;
|
||||
private YouTubeService youTubeService;
|
||||
|
||||
/**
|
||||
* Gets service instance based on service type.
|
||||
* Gets service instance based on given movie search string.
|
||||
*
|
||||
* @param serviceType Type of service instance to be returned.
|
||||
* @param movie Search string for the movie.
|
||||
* @return Service instance.
|
||||
*/
|
||||
public BusinessService getBusinessService(ServiceType serviceType) {
|
||||
if (serviceType.equals(ServiceType.EJB)) {
|
||||
return ejbService;
|
||||
public VideoStreamingService getBusinessService(String movie) {
|
||||
if (movie.toLowerCase(Locale.ROOT).contains("die hard")) {
|
||||
return netflixService;
|
||||
} else {
|
||||
return jmsService;
|
||||
return youTubeService;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,17 +24,17 @@
|
||||
package com.iluwatar.business.delegate;
|
||||
|
||||
/**
|
||||
* Client utilizes BusinessDelegate to call the business tier.
|
||||
* MobileClient utilizes BusinessDelegate to call the business tier.
|
||||
*/
|
||||
public class Client {
|
||||
public class MobileClient {
|
||||
|
||||
private final BusinessDelegate businessDelegate;
|
||||
|
||||
public Client(BusinessDelegate businessDelegate) {
|
||||
public MobileClient(BusinessDelegate businessDelegate) {
|
||||
this.businessDelegate = businessDelegate;
|
||||
}
|
||||
|
||||
public void doTask() {
|
||||
businessDelegate.doTask();
|
||||
public void playbackMovie(String movie) {
|
||||
businessDelegate.playbackMovie(movie);
|
||||
}
|
||||
}
|
@ -26,13 +26,13 @@ package com.iluwatar.business.delegate;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Service EJB implementation.
|
||||
* NetflixService implementation.
|
||||
*/
|
||||
@Slf4j
|
||||
public class EjbService implements BusinessService {
|
||||
public class NetflixService implements VideoStreamingService {
|
||||
|
||||
@Override
|
||||
public void doProcessing() {
|
||||
LOGGER.info("EjbService is now processing");
|
||||
LOGGER.info("NetflixService is now processing");
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* The MIT License
|
||||
* Copyright © 2014-2021 Ilkka Seppälä
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.iluwatar.business.delegate;
|
||||
|
||||
/**
|
||||
* Enumeration for service types.
|
||||
*/
|
||||
public enum ServiceType {
|
||||
|
||||
EJB,
|
||||
JMS
|
||||
}
|
@ -24,9 +24,9 @@
|
||||
package com.iluwatar.business.delegate;
|
||||
|
||||
/**
|
||||
* Interface for service implementations.
|
||||
* Interface for video streaming service implementations.
|
||||
*/
|
||||
public interface BusinessService {
|
||||
public interface VideoStreamingService {
|
||||
|
||||
void doProcessing();
|
||||
}
|
@ -26,13 +26,13 @@ package com.iluwatar.business.delegate;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Service JMS implementation.
|
||||
* YouTubeService implementation.
|
||||
*/
|
||||
@Slf4j
|
||||
public class JmsService implements BusinessService {
|
||||
public class YouTubeService implements VideoStreamingService {
|
||||
|
||||
@Override
|
||||
public void doProcessing() {
|
||||
LOGGER.info("JmsService is now processing");
|
||||
LOGGER.info("YouTubeService is now processing");
|
||||
}
|
||||
}
|
@ -26,25 +26,20 @@ package com.iluwatar.business.delegate;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* The Business Delegate pattern adds an abstraction layer between the presentation and business
|
||||
* tiers. By using the pattern we gain loose coupling between the tiers. The Business Delegate
|
||||
* encapsulates knowledge about how to locate, connect to, and interact with the business objects
|
||||
* that make up the application.
|
||||
*
|
||||
* <p>Some of the services the Business Delegate uses are instantiated directly, and some can be
|
||||
* retrieved through service lookups. The Business Delegate itself may contain business logic too
|
||||
* potentially tying together multiple service calls, exception handling, retrying etc.
|
||||
* Tests for the {@link BusinessDelegate}
|
||||
*/
|
||||
class BusinessDelegateTest {
|
||||
|
||||
private EjbService ejbService;
|
||||
private NetflixService netflixService;
|
||||
|
||||
private JmsService jmsService;
|
||||
private YouTubeService youTubeService;
|
||||
|
||||
private BusinessDelegate businessDelegate;
|
||||
|
||||
@ -54,19 +49,19 @@ class BusinessDelegateTest {
|
||||
*/
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ejbService = spy(new EjbService());
|
||||
jmsService = spy(new JmsService());
|
||||
netflixService = spy(new NetflixService());
|
||||
youTubeService = spy(new YouTubeService());
|
||||
|
||||
BusinessLookup businessLookup = spy(new BusinessLookup());
|
||||
businessLookup.setEjbService(ejbService);
|
||||
businessLookup.setJmsService(jmsService);
|
||||
businessLookup.setNetflixService(netflixService);
|
||||
businessLookup.setYouTubeService(youTubeService);
|
||||
|
||||
businessDelegate = spy(new BusinessDelegate());
|
||||
businessDelegate.setLookupService(businessLookup);
|
||||
}
|
||||
|
||||
/**
|
||||
* In this example the client ({@link Client}) utilizes a business delegate (
|
||||
* In this example the client ({@link MobileClient}) utilizes a business delegate (
|
||||
* {@link BusinessDelegate}) to execute a task. The Business Delegate then selects the appropriate
|
||||
* service and makes the service call.
|
||||
*/
|
||||
@ -74,26 +69,20 @@ class BusinessDelegateTest {
|
||||
void testBusinessDelegate() {
|
||||
|
||||
// setup a client object
|
||||
var client = new Client(businessDelegate);
|
||||
|
||||
// set the service type
|
||||
businessDelegate.setServiceType(ServiceType.EJB);
|
||||
var client = new MobileClient(businessDelegate);
|
||||
|
||||
// action
|
||||
client.doTask();
|
||||
client.playbackMovie("Die hard");
|
||||
|
||||
// verifying that the businessDelegate was used by client during doTask() method.
|
||||
verify(businessDelegate).doTask();
|
||||
verify(ejbService).doProcessing();
|
||||
|
||||
// set the service type
|
||||
businessDelegate.setServiceType(ServiceType.JMS);
|
||||
// verifying that the businessDelegate was used by client during playbackMovie() method.
|
||||
verify(businessDelegate).playbackMovie(anyString());
|
||||
verify(netflixService).doProcessing();
|
||||
|
||||
// action
|
||||
client.doTask();
|
||||
client.playbackMovie("Maradona");
|
||||
|
||||
// verifying that the businessDelegate was used by client during doTask() method.
|
||||
verify(businessDelegate, times(2)).doTask();
|
||||
verify(jmsService).doProcessing();
|
||||
verify(businessDelegate, times(2)).playbackMovie(anyString());
|
||||
verify(youTubeService).doProcessing();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user