Compare commits
3 Commits
master
...
business-d
Author | SHA1 | Date | |
---|---|---|---|
|
a163a46e03 | ||
|
964f2c56ad | ||
|
e0f1376bd0 |
@ -9,21 +9,156 @@ tags:
|
|||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
|
|
||||||
The Business Delegate pattern adds an abstraction layer between
|
The Business Delegate pattern adds an abstraction layer between
|
||||||
presentation and business tiers. By using the pattern we gain loose coupling
|
presentation and business tiers. By using the pattern we gain loose coupling
|
||||||
between the tiers and encapsulate knowledge about how to locate, connect to,
|
between the tiers and encapsulate knowledge about how to locate, connect to,
|
||||||
and interact with the business objects that make up the application.
|
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
|
## Class diagram
|
||||||

|
|
||||||
|

|
||||||
|
|
||||||
|
## Related patterns
|
||||||
|
|
||||||
|
* [Service locator pattern](https://java-design-patterns.com/patterns/service-locator/)
|
||||||
|
|
||||||
## Applicability
|
## Applicability
|
||||||
|
|
||||||
Use the Business Delegate pattern when
|
Use the Business Delegate pattern when
|
||||||
|
|
||||||
* you want loose coupling between presentation and business tiers
|
* You want loose coupling between presentation and business tiers
|
||||||
* you want to orchestrate calls to multiple business services
|
* You want to orchestrate calls to multiple business services
|
||||||
* you want to encapsulate service lookups and service calls
|
* 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
|
## 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)
|
* [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}
|
+ main(args : String[]) {static}
|
||||||
}
|
}
|
||||||
class BusinessDelegate {
|
class BusinessDelegate {
|
||||||
- businessService : BusinessService
|
|
||||||
- lookupService : BusinessLookup
|
- lookupService : BusinessLookup
|
||||||
- serviceType : ServiceType
|
|
||||||
+ BusinessDelegate()
|
+ BusinessDelegate()
|
||||||
+ doTask()
|
+ playbackMovie(movie : String)
|
||||||
+ setLookupService(businessLookup : BusinessLookup)
|
+ setLookupService(lookupService : BusinessLookup)
|
||||||
+ setServiceType(serviceType : ServiceType)
|
|
||||||
}
|
}
|
||||||
class BusinessLookup {
|
class BusinessLookup {
|
||||||
- ejbService : EjbService
|
- netflixService : NetflixService
|
||||||
- jmsService : JmsService
|
- youTubeService : YouTubeService
|
||||||
+ BusinessLookup()
|
+ BusinessLookup()
|
||||||
+ getBusinessService(serviceType : ServiceType) : BusinessService
|
+ getBusinessService(movie : String) : VideoStreamingService
|
||||||
+ setEjbService(ejbService : EjbService)
|
+ setNetflixService(netflixService : NetflixService)
|
||||||
+ setJmsService(jmsService : JmsService)
|
+ 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}
|
+ doProcessing() {abstract}
|
||||||
}
|
}
|
||||||
class Client {
|
class YouTubeService {
|
||||||
- businessDelegate : BusinessDelegate
|
|
||||||
+ Client(businessDelegate : BusinessDelegate)
|
|
||||||
+ doTask()
|
|
||||||
}
|
|
||||||
class EjbService {
|
|
||||||
- LOGGER : Logger {static}
|
- LOGGER : Logger {static}
|
||||||
+ EjbService()
|
+ YouTubeService()
|
||||||
+ doProcessing()
|
+ doProcessing()
|
||||||
}
|
}
|
||||||
class JmsService {
|
|
||||||
- LOGGER : Logger {static}
|
|
||||||
+ JmsService()
|
|
||||||
+ doProcessing()
|
|
||||||
}
|
}
|
||||||
enum ServiceType {
|
BusinessLookup --> "-netflixService" NetflixService
|
||||||
+ EJB {static}
|
BusinessLookup --> "-youTubeService" YouTubeService
|
||||||
+ JMS {static}
|
MobileClient --> "-businessDelegate" BusinessDelegate
|
||||||
+ valueOf(name : String) : ServiceType {static}
|
|
||||||
+ values() : ServiceType[] {static}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BusinessLookup --> "-ejbService" EjbService
|
|
||||||
BusinessDelegate --> "-serviceType" ServiceType
|
|
||||||
Client --> "-businessDelegate" BusinessDelegate
|
|
||||||
BusinessDelegate --> "-businessService" BusinessService
|
|
||||||
BusinessDelegate --> "-lookupService" BusinessLookup
|
BusinessDelegate --> "-lookupService" BusinessLookup
|
||||||
BusinessLookup --> "-jmsService" JmsService
|
NetflixService ..|> VideoStreamingService
|
||||||
EjbService ..|> BusinessService
|
YouTubeService ..|> VideoStreamingService
|
||||||
JmsService ..|> BusinessService
|
|
||||||
@enduml
|
@enduml
|
@ -33,9 +33,9 @@ package com.iluwatar.business.delegate;
|
|||||||
* retrieved through service lookups. The Business Delegate itself may contain business logic too
|
* retrieved through service lookups. The Business Delegate itself may contain business logic too
|
||||||
* potentially tying together multiple service calls, exception handling, retrying etc.
|
* potentially tying together multiple service calls, exception handling, retrying etc.
|
||||||
*
|
*
|
||||||
* <p>In this example the client ({@link Client}) utilizes a business delegate (
|
* <p>In this example the client ({@link MobileClient}) utilizes a business delegate (
|
||||||
* {@link BusinessDelegate}) to execute a task. The Business Delegate then selects the appropriate
|
* {@link BusinessDelegate}) to search for movies in video streaming services. The Business Delegate
|
||||||
* service and makes the service call.
|
* then selects the appropriate service and makes the service call.
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
@ -46,18 +46,16 @@ public class App {
|
|||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
// prepare the objects
|
||||||
var businessDelegate = new BusinessDelegate();
|
var businessDelegate = new BusinessDelegate();
|
||||||
var businessLookup = new BusinessLookup();
|
var businessLookup = new BusinessLookup();
|
||||||
businessLookup.setEjbService(new EjbService());
|
businessLookup.setNetflixService(new NetflixService());
|
||||||
businessLookup.setJmsService(new JmsService());
|
businessLookup.setYouTubeService(new YouTubeService());
|
||||||
|
|
||||||
businessDelegate.setLookupService(businessLookup);
|
businessDelegate.setLookupService(businessLookup);
|
||||||
businessDelegate.setServiceType(ServiceType.EJB);
|
|
||||||
|
|
||||||
var client = new Client(businessDelegate);
|
// create the client and use the business delegate
|
||||||
client.doTask();
|
var client = new MobileClient(businessDelegate);
|
||||||
|
client.playbackMovie("Die Hard 2");
|
||||||
businessDelegate.setServiceType(ServiceType.JMS);
|
client.playbackMovie("Maradona: The Greatest Ever");
|
||||||
client.doTask();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,24 +23,18 @@
|
|||||||
|
|
||||||
package com.iluwatar.business.delegate;
|
package com.iluwatar.business.delegate;
|
||||||
|
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BusinessDelegate separates the presentation and business tiers.
|
* BusinessDelegate separates the presentation and business tiers.
|
||||||
*/
|
*/
|
||||||
|
@Setter
|
||||||
public class BusinessDelegate {
|
public class BusinessDelegate {
|
||||||
|
|
||||||
private BusinessLookup lookupService;
|
private BusinessLookup lookupService;
|
||||||
private ServiceType serviceType;
|
|
||||||
|
|
||||||
public void setLookupService(BusinessLookup businessLookup) {
|
public void playbackMovie(String movie) {
|
||||||
this.lookupService = businessLookup;
|
VideoStreamingService videoStreamingService = lookupService.getBusinessService(movie);
|
||||||
}
|
videoStreamingService.doProcessing();
|
||||||
|
|
||||||
public void setServiceType(ServiceType serviceType) {
|
|
||||||
this.serviceType = serviceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doTask() {
|
|
||||||
BusinessService businessService = lookupService.getBusinessService(serviceType);
|
|
||||||
businessService.doProcessing();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
package com.iluwatar.business.delegate;
|
package com.iluwatar.business.delegate;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,21 +32,21 @@ import lombok.Setter;
|
|||||||
@Setter
|
@Setter
|
||||||
public class BusinessLookup {
|
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.
|
* @return Service instance.
|
||||||
*/
|
*/
|
||||||
public BusinessService getBusinessService(ServiceType serviceType) {
|
public VideoStreamingService getBusinessService(String movie) {
|
||||||
if (serviceType.equals(ServiceType.EJB)) {
|
if (movie.toLowerCase(Locale.ROOT).contains("die hard")) {
|
||||||
return ejbService;
|
return netflixService;
|
||||||
} else {
|
} else {
|
||||||
return jmsService;
|
return youTubeService;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,17 +24,17 @@
|
|||||||
package com.iluwatar.business.delegate;
|
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;
|
private final BusinessDelegate businessDelegate;
|
||||||
|
|
||||||
public Client(BusinessDelegate businessDelegate) {
|
public MobileClient(BusinessDelegate businessDelegate) {
|
||||||
this.businessDelegate = businessDelegate;
|
this.businessDelegate = businessDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doTask() {
|
public void playbackMovie(String movie) {
|
||||||
businessDelegate.doTask();
|
businessDelegate.playbackMovie(movie);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -26,13 +26,13 @@ package com.iluwatar.business.delegate;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service EJB implementation.
|
* NetflixService implementation.
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class EjbService implements BusinessService {
|
public class NetflixService implements VideoStreamingService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doProcessing() {
|
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;
|
package com.iluwatar.business.delegate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for service implementations.
|
* Interface for video streaming service implementations.
|
||||||
*/
|
*/
|
||||||
public interface BusinessService {
|
public interface VideoStreamingService {
|
||||||
|
|
||||||
void doProcessing();
|
void doProcessing();
|
||||||
}
|
}
|
@ -26,13 +26,13 @@ package com.iluwatar.business.delegate;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service JMS implementation.
|
* YouTubeService implementation.
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class JmsService implements BusinessService {
|
public class YouTubeService implements VideoStreamingService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doProcessing() {
|
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.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Business Delegate pattern adds an abstraction layer between the presentation and business
|
* Tests for the {@link BusinessDelegate}
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
class BusinessDelegateTest {
|
class BusinessDelegateTest {
|
||||||
|
|
||||||
private EjbService ejbService;
|
private NetflixService netflixService;
|
||||||
|
|
||||||
private JmsService jmsService;
|
private YouTubeService youTubeService;
|
||||||
|
|
||||||
private BusinessDelegate businessDelegate;
|
private BusinessDelegate businessDelegate;
|
||||||
|
|
||||||
@ -54,19 +49,19 @@ class BusinessDelegateTest {
|
|||||||
*/
|
*/
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
ejbService = spy(new EjbService());
|
netflixService = spy(new NetflixService());
|
||||||
jmsService = spy(new JmsService());
|
youTubeService = spy(new YouTubeService());
|
||||||
|
|
||||||
BusinessLookup businessLookup = spy(new BusinessLookup());
|
BusinessLookup businessLookup = spy(new BusinessLookup());
|
||||||
businessLookup.setEjbService(ejbService);
|
businessLookup.setNetflixService(netflixService);
|
||||||
businessLookup.setJmsService(jmsService);
|
businessLookup.setYouTubeService(youTubeService);
|
||||||
|
|
||||||
businessDelegate = spy(new BusinessDelegate());
|
businessDelegate = spy(new BusinessDelegate());
|
||||||
businessDelegate.setLookupService(businessLookup);
|
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
|
* {@link BusinessDelegate}) to execute a task. The Business Delegate then selects the appropriate
|
||||||
* service and makes the service call.
|
* service and makes the service call.
|
||||||
*/
|
*/
|
||||||
@ -74,26 +69,20 @@ class BusinessDelegateTest {
|
|||||||
void testBusinessDelegate() {
|
void testBusinessDelegate() {
|
||||||
|
|
||||||
// setup a client object
|
// setup a client object
|
||||||
var client = new Client(businessDelegate);
|
var client = new MobileClient(businessDelegate);
|
||||||
|
|
||||||
// set the service type
|
|
||||||
businessDelegate.setServiceType(ServiceType.EJB);
|
|
||||||
|
|
||||||
// action
|
// action
|
||||||
client.doTask();
|
client.playbackMovie("Die hard");
|
||||||
|
|
||||||
// verifying that the businessDelegate was used by client during doTask() method.
|
// verifying that the businessDelegate was used by client during playbackMovie() method.
|
||||||
verify(businessDelegate).doTask();
|
verify(businessDelegate).playbackMovie(anyString());
|
||||||
verify(ejbService).doProcessing();
|
verify(netflixService).doProcessing();
|
||||||
|
|
||||||
// set the service type
|
|
||||||
businessDelegate.setServiceType(ServiceType.JMS);
|
|
||||||
|
|
||||||
// action
|
// action
|
||||||
client.doTask();
|
client.playbackMovie("Maradona");
|
||||||
|
|
||||||
// verifying that the businessDelegate was used by client during doTask() method.
|
// verifying that the businessDelegate was used by client during doTask() method.
|
||||||
verify(businessDelegate, times(2)).doTask();
|
verify(businessDelegate, times(2)).playbackMovie(anyString());
|
||||||
verify(jmsService).doProcessing();
|
verify(youTubeService).doProcessing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user