Merge branch 'master' of https://github.com/iluwatar/java-design-patterns
This commit is contained in:
commit
9e58edf05e
@ -26,63 +26,60 @@ package com.iluwatar.pageobject;
|
||||
import java.awt.Desktop;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Page Object pattern wraps an UI component with an application specific API allowing you to
|
||||
* manipulate the UI elements without having to dig around with the underlying UI technology used. This is
|
||||
* especially useful for testing as it means your tests will be less brittle. Your tests can concentrate on
|
||||
* the actual test cases where as the manipulation of the UI can be left to the internals of the page object
|
||||
* itself.
|
||||
* manipulate the UI elements without having to dig around with the underlying UI technology used.
|
||||
* This is especially useful for testing as it means your tests will be less brittle. Your tests can
|
||||
* concentrate on the actual test cases where as the manipulation of the UI can be left to the
|
||||
* internals of the page object itself.
|
||||
*
|
||||
* <p>
|
||||
* Due to this reason, it has become very popular within the test automation community.
|
||||
* In particular, it is very common in that the page object is used to represent the html pages of a
|
||||
* web application that is under test. This web application is referred to as AUT (Application Under Test).
|
||||
* A web browser automation tool/framework like Selenium for instance, is then used to drive the automating
|
||||
* of the browser navigation and user actions journeys through this web application. Your test class would
|
||||
* therefore only be responsible for particular test cases and page object would be used by the test class
|
||||
* for UI manipulation required for the tests.
|
||||
* <p>Due to this reason, it has become very popular within the test automation community. In
|
||||
* particular, it is very common in that the page object is used to represent the html pages of a
|
||||
* web application that is under test. This web application is referred to as AUT (Application Under
|
||||
* Test). A web browser automation tool/framework like Selenium for instance, is then used to drive
|
||||
* the automating of the browser navigation and user actions journeys through this web application.
|
||||
* Your test class would therefore only be responsible for particular test cases and page object
|
||||
* would be used by the test class for UI manipulation required for the tests.
|
||||
*
|
||||
* <p>
|
||||
* In this implementation rather than using Selenium, the HtmlUnit library is used as a replacement to
|
||||
* represent the specific html elements and to drive the browser. The purpose of this example is just to
|
||||
* provide a simple version that showcase the intentions of this pattern and how this pattern is used
|
||||
* in order to understand it.
|
||||
* <p>In this implementation rather than using Selenium, the HtmlUnit library is used as a
|
||||
* replacement to represent the specific html elements and to drive the browser. The purpose of this
|
||||
* example is just to provide a simple version that showcase the intentions of this pattern and how
|
||||
* this pattern is used in order to understand it.
|
||||
*/
|
||||
public final class App {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||
|
||||
private App() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Application entry point
|
||||
*
|
||||
* <p>
|
||||
* The application under development is a web application. Normally you would probably have a
|
||||
* backend that is probably implemented in an object-oriented language (e.g. Java) that serves
|
||||
* the frontend which comprises of a series of HTML, CSS, JS etc...
|
||||
* <p>The application under development is a web application. Normally you would probably have a
|
||||
* backend that is probably implemented in an object-oriented language (e.g. Java) that serves the
|
||||
* frontend which comprises of a series of HTML, CSS, JS etc...
|
||||
*
|
||||
* <p>
|
||||
* For illustrations purposes only, a very simple static html app is used here. This main method
|
||||
* just fires up this simple web app in a default browser.
|
||||
* <p>For illustrations purposes only, a very simple static html app is used here. This main
|
||||
* method just fires up this simple web app in a default browser.
|
||||
*
|
||||
* @param args arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
try {
|
||||
File applicationFile = new File(App.class.getClassLoader().getResource("sample-ui/login.html").getPath());
|
||||
File applicationFile =
|
||||
new File(App.class.getClassLoader().getResource("sample-ui/login.html").getPath());
|
||||
|
||||
// should work for unix like OS (mac, unix etc...)
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
Desktop.getDesktop().open(applicationFile);
|
||||
|
||||
} else {
|
||||
// java Desktop not supported - above unlikely to work for Windows so try following instead...
|
||||
// java Desktop not supported - above unlikely to work for Windows so try instead...
|
||||
Runtime.getRuntime().exec("cmd.exe start " + applicationFile);
|
||||
}
|
||||
|
||||
|
@ -29,25 +29,23 @@ import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Page Object pattern wraps an UI component with an application specific API allowing you to
|
||||
* manipulate the UI elements without having to dig around with the underlying UI technology used. This is
|
||||
* especially useful for testing as it means your tests will be less brittle. Your tests can concentrate on
|
||||
* the actual test cases where as the manipulation of the UI can be left to the internals of the page object
|
||||
* itself.
|
||||
* manipulate the UI elements without having to dig around with the underlying UI technology used.
|
||||
* This is especially useful for testing as it means your tests will be less brittle. Your tests can
|
||||
* concentrate on the actual test cases where as the manipulation of the UI can be left to the
|
||||
* internals of the page object itself.
|
||||
*
|
||||
* <p>
|
||||
* Due to this reason, it has become very popular within the test automation community.
|
||||
* In particular, it is very common in that the page object is used to represent the html pages of a
|
||||
* web application that is under test. This web application is referred to as AUT (Application Under Test).
|
||||
* A web browser automation tool/framework like Selenium for instance, is then used to drive the automating
|
||||
* of the browser navigation and user actions journeys through this web application. Your test class would
|
||||
* therefore only be responsible for particular test cases and page object would be used by the test class
|
||||
* for UI manipulation required for the tests.
|
||||
* <p>Due to this reason, it has become very popular within the test automation community. In
|
||||
* particular, it is very common in that the page object is used to represent the html pages of a
|
||||
* web application that is under test. This web application is referred to as AUT (Application Under
|
||||
* Test). A web browser automation tool/framework like Selenium for instance, is then used to drive
|
||||
* the automating of the browser navigation and user actions journeys through this web application.
|
||||
* Your test class would therefore only be responsible for particular test cases and page object
|
||||
* would be used by the test class for UI manipulation required for the tests.
|
||||
*
|
||||
* <p>
|
||||
* In this implementation rather than using Selenium, the HtmlUnit library is used as a replacement to
|
||||
* represent the specific html elements and to drive the browser. The purpose of this example is just to
|
||||
* provide a simple version that showcase the intentions of this pattern and how this pattern is used
|
||||
* in order to understand it.
|
||||
* <p>In this implementation rather than using Selenium, the HtmlUnit library is used as a
|
||||
* replacement to represent the specific html elements and to drive the browser. The purpose of this
|
||||
* example is just to provide a simple version that showcase the intentions of this pattern and how
|
||||
* this pattern is used in order to understand it.
|
||||
*/
|
||||
public final class App {
|
||||
|
||||
@ -57,21 +55,20 @@ public final class App {
|
||||
/**
|
||||
* Application entry point
|
||||
*
|
||||
* <p>
|
||||
* The application under development is a web application. Normally you would probably have a
|
||||
* backend that is probably implemented in an object-oriented language (e.g. Java) that serves
|
||||
* the frontend which comprises of a series of HTML, CSS, JS etc...
|
||||
* <p>The application under development is a web application. Normally you would probably have a
|
||||
* backend that is probably implemented in an object-oriented language (e.g. Java) that serves the
|
||||
* frontend which comprises of a series of HTML, CSS, JS etc...
|
||||
*
|
||||
* <p>
|
||||
* For illustrations purposes only, a very simple static html app is used here. This main method
|
||||
* just fires up this simple web app in a default browser.
|
||||
* <p>For illustrations purposes only, a very simple static html app is used here. This main
|
||||
* method just fires up this simple web app in a default browser.
|
||||
*
|
||||
* @param args arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
try {
|
||||
File applicationFile = new File(App.class.getClassLoader().getResource("sample-ui/login.html").getPath());
|
||||
File applicationFile =
|
||||
new File(App.class.getClassLoader().getResource("sample-ui/login.html").getPath());
|
||||
|
||||
// should work for unix like OS (mac, unix etc...)
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
|
@ -26,10 +26,8 @@ package com.iluwatar.pageobject;
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -46,7 +44,7 @@ public class AlbumListPage extends Page {
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*/
|
||||
public AlbumListPage(WebClient webClient) {
|
||||
super(webClient);
|
||||
@ -54,7 +52,7 @@ public class AlbumListPage extends Page {
|
||||
|
||||
|
||||
/**
|
||||
* Navigates to the Album List Page
|
||||
* Navigates to the Album List Page.
|
||||
*
|
||||
* @return {@link AlbumListPage}
|
||||
*/
|
||||
@ -76,7 +74,7 @@ public class AlbumListPage extends Page {
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects an album by the given album title
|
||||
* Selects an album by the given album title.
|
||||
*
|
||||
* @param albumTitle the title of the album to click
|
||||
* @return the album page
|
||||
|
@ -23,11 +23,6 @@
|
||||
|
||||
package com.iluwatar.pageobject;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlNumberInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlOption;
|
||||
@ -35,6 +30,9 @@ import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
|
||||
import java.io.IOException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Page Object encapsulating the Album Page (album-page.html)
|
||||
@ -49,7 +47,7 @@ public class AlbumPage extends Page {
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*/
|
||||
public AlbumPage(WebClient webClient) {
|
||||
super(webClient);
|
||||
@ -57,7 +55,7 @@ public class AlbumPage extends Page {
|
||||
|
||||
|
||||
/**
|
||||
* Navigates to the album page
|
||||
* Navigates to the album page.
|
||||
*
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
@ -81,7 +79,7 @@ public class AlbumPage extends Page {
|
||||
|
||||
|
||||
/**
|
||||
* Sets the album title input text field
|
||||
* Sets the album title input text field.
|
||||
*
|
||||
* @param albumTitle the new album title value to set
|
||||
* @return {@link AlbumPage}
|
||||
@ -94,7 +92,7 @@ public class AlbumPage extends Page {
|
||||
|
||||
|
||||
/**
|
||||
* Sets the artist input text field
|
||||
* Sets the artist input text field.
|
||||
*
|
||||
* @param artist the new artist value to set
|
||||
* @return {@link AlbumPage}
|
||||
@ -107,7 +105,7 @@ public class AlbumPage extends Page {
|
||||
|
||||
|
||||
/**
|
||||
* Selects the select's option value based on the year value given
|
||||
* Selects the select's option value based on the year value given.
|
||||
*
|
||||
* @param year the new year value to set
|
||||
* @return {@link AlbumPage}
|
||||
@ -121,7 +119,7 @@ public class AlbumPage extends Page {
|
||||
|
||||
|
||||
/**
|
||||
* Sets the album rating input text field
|
||||
* Sets the album rating input text field.
|
||||
*
|
||||
* @param albumRating the new album rating value to set
|
||||
* @return {@link AlbumPage}
|
||||
@ -133,20 +131,21 @@ public class AlbumPage extends Page {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of songs number input field
|
||||
* Sets the number of songs number input field.
|
||||
*
|
||||
* @param numberOfSongs the new number of songs value to be set
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
public AlbumPage changeNumberOfSongs(int numberOfSongs) {
|
||||
HtmlNumberInput numberOfSongsNumberField = (HtmlNumberInput) page.getElementById("numberOfSongs");
|
||||
HtmlNumberInput numberOfSongsNumberField =
|
||||
(HtmlNumberInput) page.getElementById("numberOfSongs");
|
||||
numberOfSongsNumberField.setText(Integer.toString(numberOfSongs));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cancel changes made by clicking the cancel button
|
||||
* Cancel changes made by clicking the cancel button.
|
||||
*
|
||||
* @return {@link AlbumListPage}
|
||||
*/
|
||||
@ -162,7 +161,7 @@ public class AlbumPage extends Page {
|
||||
|
||||
|
||||
/**
|
||||
* Saves changes made by clicking the save button
|
||||
* Saves changes made by clicking the save button.
|
||||
*
|
||||
* @return {@link AlbumPage}
|
||||
*/
|
||||
|
@ -29,7 +29,6 @@ import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -45,7 +44,7 @@ public class LoginPage extends Page {
|
||||
private HtmlPage page;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param webClient {@link WebClient}
|
||||
*/
|
||||
@ -54,7 +53,7 @@ public class LoginPage extends Page {
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates to the Login page
|
||||
* Navigates to the Login page.
|
||||
*
|
||||
* @return {@link LoginPage}
|
||||
*/
|
||||
@ -77,7 +76,7 @@ public class LoginPage extends Page {
|
||||
|
||||
|
||||
/**
|
||||
* Enters the username into the username input text field
|
||||
* Enters the username into the username input text field.
|
||||
*
|
||||
* @param username the username to enter
|
||||
* @return {@link LoginPage}
|
||||
@ -90,23 +89,24 @@ public class LoginPage extends Page {
|
||||
|
||||
|
||||
/**
|
||||
* Enters the password into the password input password field
|
||||
* Enters the password into the password input password field.
|
||||
*
|
||||
* @param password the password to enter
|
||||
* @return {@link LoginPage}
|
||||
*/
|
||||
public LoginPage enterPassword(String password) {
|
||||
HtmlPasswordInput passwordInputPasswordField = (HtmlPasswordInput) page.getElementById("password");
|
||||
HtmlPasswordInput passwordInputPasswordField =
|
||||
(HtmlPasswordInput) page.getElementById("password");
|
||||
passwordInputPasswordField.setText(password);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clicking on the login button to 'login'
|
||||
* Clicking on the login button to 'login'.
|
||||
*
|
||||
* @return {@link AlbumListPage}
|
||||
* - this is the page that user gets navigated to once successfully logged in
|
||||
* @return {@link AlbumListPage} - this is the page that user gets navigated to once successfully
|
||||
* logged in
|
||||
*/
|
||||
public AlbumListPage login() {
|
||||
HtmlSubmitInput loginButton = (HtmlSubmitInput) page.getElementById("loginButton");
|
||||
|
@ -26,20 +26,19 @@ package com.iluwatar.pageobject;
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
|
||||
/**
|
||||
* Encapsulation for a generic 'Page'
|
||||
* Encapsulation for a generic 'Page'.
|
||||
*/
|
||||
public abstract class Page {
|
||||
|
||||
/**
|
||||
* Application Under Test path
|
||||
* This directory location is where html web pages are located
|
||||
* Application Under Test path This directory location is where html web pages are located.
|
||||
*/
|
||||
public static final String AUT_PATH = "../sample-application/src/main/resources/sample-ui/";
|
||||
|
||||
protected final WebClient webClient;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*
|
||||
* @param webClient {@link WebClient}
|
||||
*/
|
||||
@ -48,7 +47,7 @@ public abstract class Page {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the current page is actually the page this page object represents
|
||||
* Checks that the current page is actually the page this page object represents.
|
||||
*
|
||||
* @return true if so, otherwise false
|
||||
*/
|
||||
|
@ -23,18 +23,16 @@
|
||||
|
||||
package com.iluwatar.partialresponse;
|
||||
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The Partial response pattern is a design pattern in which client specifies fields to fetch to serve.
|
||||
* Here {@link App} is playing as client for {@link VideoResource} server.
|
||||
* Client ask for specific fields information in video to server.
|
||||
* <p>
|
||||
* <p>
|
||||
* {@link VideoResource} act as server to serve video information.
|
||||
* The Partial response pattern is a design pattern in which client specifies fields to fetch to
|
||||
* serve. Here {@link App} is playing as client for {@link VideoResource} server. Client ask for
|
||||
* specific fields information in video to server.
|
||||
*
|
||||
* <p>{@link VideoResource} act as server to serve video information.
|
||||
*/
|
||||
|
||||
public class App {
|
||||
@ -47,12 +45,12 @@ public class App {
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
Map<Integer, Video> videos = Map.of(
|
||||
1, new Video(1, "Avatar", 178, "epic science fiction film",
|
||||
"James Cameron", "English"),
|
||||
2, new Video(2, "Godzilla Resurgence", 120, "Action & drama movie|",
|
||||
"Hideaki Anno", "Japanese"),
|
||||
3, new Video(3, "Interstellar", 169, "Adventure & Sci-Fi",
|
||||
"Christopher Nolan", "English"));
|
||||
1, new Video(1, "Avatar", 178, "epic science fiction film",
|
||||
"James Cameron", "English"),
|
||||
2, new Video(2, "Godzilla Resurgence", 120, "Action & drama movie|",
|
||||
"Hideaki Anno", "Japanese"),
|
||||
3, new Video(3, "Interstellar", 169, "Adventure & Sci-Fi",
|
||||
"Christopher Nolan", "English"));
|
||||
VideoResource videoResource = new VideoResource(new FieldJsonMapper(), videos);
|
||||
|
||||
|
||||
|
@ -26,11 +26,13 @@ package com.iluwatar.partialresponse;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Map a video to json
|
||||
* Map a video to json.
|
||||
*/
|
||||
public class FieldJsonMapper {
|
||||
|
||||
/**
|
||||
* Gets json of required fields from video.
|
||||
*
|
||||
* @param video object containing video information
|
||||
* @param fields fields information to get
|
||||
* @return json of required fields from video
|
||||
|
@ -24,8 +24,7 @@
|
||||
package com.iluwatar.partialresponse;
|
||||
|
||||
/**
|
||||
* {@link Video} is a entity to serve from server.It contains all video related information..
|
||||
* <p>
|
||||
* {@link Video} is a entity to serve from server.It contains all video related information.
|
||||
*/
|
||||
public class Video {
|
||||
private final Integer id;
|
||||
@ -36,23 +35,27 @@ public class Video {
|
||||
private final String language;
|
||||
|
||||
/**
|
||||
* @param id video unique id
|
||||
* @param title video title
|
||||
* @param length video length in minutes
|
||||
* @param description video description by publisher
|
||||
* @param director video director name
|
||||
* @param language video language {private, public}
|
||||
* Constructor.
|
||||
*
|
||||
* @param id video unique id
|
||||
* @param title video title
|
||||
* @param len video length in minutes
|
||||
* @param desc video description by publisher
|
||||
* @param director video director name
|
||||
* @param lang video language {private, public}
|
||||
*/
|
||||
public Video(Integer id, String title, Integer length, String description, String director, String language) {
|
||||
public Video(Integer id, String title, Integer len, String desc, String director, String lang) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.length = length;
|
||||
this.description = description;
|
||||
this.length = len;
|
||||
this.description = desc;
|
||||
this.director = director;
|
||||
this.language = language;
|
||||
this.language = lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* ToString.
|
||||
*
|
||||
* @return json representaion of video
|
||||
*/
|
||||
@Override
|
||||
|
@ -26,14 +26,16 @@ package com.iluwatar.partialresponse;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The resource class which serves video information.
|
||||
* This class act as server in the demo. Which has all video details.
|
||||
* The resource class which serves video information. This class act as server in the demo. Which
|
||||
* has all video details.
|
||||
*/
|
||||
public class VideoResource {
|
||||
private FieldJsonMapper fieldJsonMapper;
|
||||
private Map<Integer, Video> videos;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param fieldJsonMapper map object to json.
|
||||
* @param videos initialize resource with existing videos. Act as database.
|
||||
*/
|
||||
@ -43,6 +45,8 @@ public class VideoResource {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Details.
|
||||
*
|
||||
* @param id video id
|
||||
* @param fields fields to get information about
|
||||
* @return full response if no fields specified else partial response for given field.
|
||||
|
@ -24,21 +24,20 @@
|
||||
package com.iluwatar.pipeline;
|
||||
|
||||
/**
|
||||
* The Pipeline pattern uses ordered stages to process a sequence of input values.
|
||||
* Each implemented task is represented by a stage of the pipeline. You can think of
|
||||
* pipelines as similar to assembly lines in a factory, where each item in the assembly
|
||||
* line is constructed in stages. The partially assembled item is passed from one assembly
|
||||
* stage to another. The outputs of the assembly line occur in the same order as that of the
|
||||
* inputs.
|
||||
* The Pipeline pattern uses ordered stages to process a sequence of input values. Each implemented
|
||||
* task is represented by a stage of the pipeline. You can think of pipelines as similar to assembly
|
||||
* lines in a factory, where each item in the assembly line is constructed in stages. The partially
|
||||
* assembled item is passed from one assembly stage to another. The outputs of the assembly line
|
||||
* occur in the same order as that of the inputs.
|
||||
*
|
||||
* Classes used in this example are suffixed with "Handlers", and synonymously refers to the
|
||||
* <p>Classes used in this example are suffixed with "Handlers", and synonymously refers to the
|
||||
* "stage".
|
||||
*/
|
||||
public class App {
|
||||
/**
|
||||
* Specify the initial input type for the first stage handler and the expected output type
|
||||
* of the last stage handler as type parameters for Pipeline. Use the fluent builder by
|
||||
* calling addHandler to add more stage handlers on the pipeline.
|
||||
* Specify the initial input type for the first stage handler and the expected output type of the
|
||||
* last stage handler as type parameters for Pipeline. Use the fluent builder by calling
|
||||
* addHandler to add more stage handlers on the pipeline.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
/*
|
||||
|
@ -23,11 +23,10 @@
|
||||
|
||||
package com.iluwatar.pipeline;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Stage handler that converts an input String to its char[] array counterpart.
|
||||
*/
|
||||
@ -38,8 +37,10 @@ class ConvertToCharArrayHandler implements Handler<String, char[]> {
|
||||
@Override
|
||||
public char[] process(String input) {
|
||||
char[] characters = input.toCharArray();
|
||||
LOGGER.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
|
||||
ConvertToCharArrayHandler.class, input, String.class, Arrays.toString(characters), Character[].class));
|
||||
LOGGER
|
||||
.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
|
||||
ConvertToCharArrayHandler.class, input, String.class, Arrays
|
||||
.toString(characters), Character[].class));
|
||||
|
||||
return characters;
|
||||
}
|
||||
|
@ -24,7 +24,9 @@
|
||||
package com.iluwatar.pipeline;
|
||||
|
||||
/**
|
||||
* Forms a contract to all stage handlers to accept a certain type of input and return a processed output.
|
||||
* Forms a contract to all stage handlers to accept a certain type of input and return a processed
|
||||
* output.
|
||||
*
|
||||
* @param <I> the input type of the handler
|
||||
* @param <O> the processed output type of the handler
|
||||
*/
|
||||
|
@ -24,8 +24,9 @@
|
||||
package com.iluwatar.pipeline;
|
||||
|
||||
/**
|
||||
* Main Pipeline class that initially sets the current handler. Processed output
|
||||
* of the initial handler is then passed as the input to the next stage handlers.
|
||||
* Main Pipeline class that initially sets the current handler. Processed output of the initial
|
||||
* handler is then passed as the input to the next stage handlers.
|
||||
*
|
||||
* @param <I> the type of the input for the first stage handler
|
||||
* @param <O> the final stage handler's output type
|
||||
*/
|
||||
|
@ -27,7 +27,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Stage handler that returns a new instance of String without the alphabet characters of the input string.
|
||||
* Stage handler that returns a new instance of String without the alphabet characters of the input
|
||||
* string.
|
||||
*/
|
||||
class RemoveAlphabetsHandler implements Handler<String, String> {
|
||||
|
||||
@ -47,8 +48,13 @@ class RemoveAlphabetsHandler implements Handler<String, String> {
|
||||
}
|
||||
|
||||
String inputWithoutAlphabetsStr = inputWithoutAlphabets.toString();
|
||||
LOGGER.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
|
||||
RemoveAlphabetsHandler.class, input, String.class, inputWithoutAlphabetsStr, String.class));
|
||||
LOGGER.info(
|
||||
String.format(
|
||||
"Current handler: %s, input is %s of type %s, output is %s, of type %s",
|
||||
RemoveAlphabetsHandler.class, input,
|
||||
String.class, inputWithoutAlphabetsStr, String.class
|
||||
)
|
||||
);
|
||||
|
||||
return inputWithoutAlphabetsStr;
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Stage handler that returns a new instance of String without the digit characters of the input string.
|
||||
* Stage handler that returns a new instance of String without the digit characters of the input
|
||||
* string.
|
||||
*/
|
||||
class RemoveDigitsHandler implements Handler<String, String> {
|
||||
|
||||
@ -47,8 +48,9 @@ class RemoveDigitsHandler implements Handler<String, String> {
|
||||
}
|
||||
|
||||
String inputWithoutDigitsStr = inputWithoutDigits.toString();
|
||||
LOGGER.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
|
||||
RemoveDigitsHandler.class, input, String.class, inputWithoutDigitsStr, String.class));
|
||||
LOGGER
|
||||
.info(String.format("Current handler: %s, input is %s of type %s, output is %s, of type %s",
|
||||
RemoveDigitsHandler.class, input, String.class, inputWithoutDigitsStr, String.class));
|
||||
|
||||
return inputWithoutDigitsStr;
|
||||
}
|
||||
|
@ -30,16 +30,15 @@ package com.iluwatar.poison.pill;
|
||||
* Pill will stop reading messages from the queue. You must also ensure that the Poison Pill will be
|
||||
* the last message that will be read from the queue (if you have prioritized queue then this can be
|
||||
* tricky).
|
||||
* <p>
|
||||
* In simple cases the Poison Pill can be just a null-reference, but holding a unique separate
|
||||
*
|
||||
* <p>In simple cases the Poison Pill can be just a null-reference, but holding a unique separate
|
||||
* shared object-marker (with name "Poison" or "Poison Pill") is more clear and self describing.
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
||||
/**
|
||||
* Program entry point
|
||||
*
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
@ -28,10 +28,10 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Class responsible for receiving and handling submitted to the queue messages
|
||||
* Class responsible for receiving and handling submitted to the queue messages.
|
||||
*/
|
||||
public class Consumer {
|
||||
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(Consumer.class);
|
||||
|
||||
private final MqSubscribePoint queue;
|
||||
@ -43,7 +43,7 @@ public class Consumer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume message
|
||||
* Consume message.
|
||||
*/
|
||||
public void consume() {
|
||||
while (true) {
|
||||
|
@ -65,7 +65,7 @@ public interface Message {
|
||||
};
|
||||
|
||||
/**
|
||||
* Enumeration of Type of Headers
|
||||
* Enumeration of Type of Headers.
|
||||
*/
|
||||
enum Headers {
|
||||
DATE, SENDER
|
||||
|
@ -24,7 +24,7 @@
|
||||
package com.iluwatar.poison.pill;
|
||||
|
||||
/**
|
||||
* Represents abstraction of channel (or pipe) that bounds {@link Producer} and {@link Consumer}
|
||||
* Represents abstraction of channel (or pipe) that bounds {@link Producer} and {@link Consumer}.
|
||||
*/
|
||||
public interface MessageQueue extends MqPublishPoint, MqSubscribePoint {
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
package com.iluwatar.poison.pill;
|
||||
|
||||
/**
|
||||
* Endpoint to publish {@link Message} to queue
|
||||
* Endpoint to publish {@link Message} to queue.
|
||||
*/
|
||||
public interface MqPublishPoint {
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
package com.iluwatar.poison.pill;
|
||||
|
||||
/**
|
||||
* Endpoint to retrieve {@link Message} from queue
|
||||
* Endpoint to retrieve {@link Message} from queue.
|
||||
*/
|
||||
public interface MqSubscribePoint {
|
||||
|
||||
|
@ -23,15 +23,14 @@
|
||||
|
||||
package com.iluwatar.poison.pill;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.iluwatar.poison.pill.Message.Headers;
|
||||
import java.util.Date;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Class responsible for producing unit of work that can be expressed as message and submitted to
|
||||
* queue
|
||||
* queue.
|
||||
*/
|
||||
public class Producer {
|
||||
|
||||
@ -42,7 +41,7 @@ public class Producer {
|
||||
private boolean isStopped;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*/
|
||||
public Producer(String name, MqPublishPoint queue) {
|
||||
this.name = name;
|
||||
@ -51,7 +50,7 @@ public class Producer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send message to queue
|
||||
* Send message to queue.
|
||||
*/
|
||||
public void send(String body) {
|
||||
if (isStopped) {
|
||||
@ -72,7 +71,7 @@ public class Producer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop system by sending poison pill
|
||||
* Stop system by sending poison pill.
|
||||
*/
|
||||
public void stop() {
|
||||
isStopped = true;
|
||||
|
@ -28,7 +28,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link Message} basic implementation
|
||||
* {@link Message} basic implementation.
|
||||
*/
|
||||
public class SimpleMessage implements Message {
|
||||
|
||||
|
@ -27,7 +27,7 @@ import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* Bounded blocking queue wrapper
|
||||
* Bounded blocking queue wrapper.
|
||||
*/
|
||||
public class SimpleMessageQueue implements MessageQueue {
|
||||
|
||||
|
@ -25,16 +25,15 @@ package com.iluwatar.priority.queue;
|
||||
|
||||
/**
|
||||
* Prioritize requests sent to services so that requests with a higher priority are received and
|
||||
* processed more quickly than those of a lower priority.
|
||||
* This pattern is useful in applications that offer different service level guarantees
|
||||
* to individual clients.
|
||||
* Example :Send multiple message with different priority to worker queue.
|
||||
* Worker execute higher priority message first
|
||||
* processed more quickly than those of a lower priority. This pattern is useful in applications
|
||||
* that offer different service level guarantees to individual clients. Example :Send multiple
|
||||
* message with different priority to worker queue. Worker execute higher priority message first
|
||||
*
|
||||
* @see "https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn589794(v=pandp.10)"
|
||||
*/
|
||||
public class Application {
|
||||
/**
|
||||
* main entry
|
||||
* main entry.
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
package com.iluwatar.priority.queue;
|
||||
|
||||
/**
|
||||
* Message bean
|
||||
* Message bean.
|
||||
*/
|
||||
public class Message implements Comparable<Message> {
|
||||
private final String message;
|
||||
|
@ -23,11 +23,11 @@
|
||||
|
||||
package com.iluwatar.priority.queue;
|
||||
|
||||
import static java.util.Arrays.copyOf;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static java.util.Arrays.copyOf;
|
||||
|
||||
/**
|
||||
* Keep high Priority message on top using maxHeap.
|
||||
*
|
||||
@ -50,14 +50,14 @@ public class PriorityMessageQueue<T extends Comparable> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove top message from queue
|
||||
* Remove top message from queue.
|
||||
*/
|
||||
public T remove() {
|
||||
if (isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
T root = queue[0];
|
||||
final T root = queue[0];
|
||||
queue[0] = queue[size - 1];
|
||||
size--;
|
||||
maxHeapifyDown();
|
||||
@ -65,7 +65,7 @@ public class PriorityMessageQueue<T extends Comparable> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add message to queue
|
||||
* Add message to queue.
|
||||
*/
|
||||
public void add(T t) {
|
||||
ensureCapacity();
|
||||
@ -75,7 +75,7 @@ public class PriorityMessageQueue<T extends Comparable> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check queue size
|
||||
* Check queue size.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
|
@ -24,7 +24,7 @@
|
||||
package com.iluwatar.priority.queue;
|
||||
|
||||
/**
|
||||
* Manage priority queue
|
||||
* Manage priority queue.
|
||||
*/
|
||||
public class QueueManager {
|
||||
/*
|
||||
@ -37,7 +37,7 @@ public class QueueManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish message to queue
|
||||
* Publish message to queue.
|
||||
*/
|
||||
public void publishMessage(Message message) {
|
||||
messagePriorityMessageQueue.add(message);
|
||||
@ -45,7 +45,7 @@ public class QueueManager {
|
||||
|
||||
|
||||
/**
|
||||
* recive message from queue
|
||||
* recive message from queue.
|
||||
*/
|
||||
public Message receiveMessage() {
|
||||
if (messagePriorityMessageQueue.isEmpty()) {
|
||||
|
@ -27,7 +27,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Message Worker
|
||||
* Message Worker.
|
||||
*/
|
||||
public class Worker {
|
||||
|
||||
@ -40,7 +40,7 @@ public class Worker {
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep checking queue for message
|
||||
* Keep checking queue for message.
|
||||
*/
|
||||
@SuppressWarnings("squid:S2189")
|
||||
public void run() throws Exception {
|
||||
@ -56,7 +56,7 @@ public class Worker {
|
||||
}
|
||||
|
||||
/**
|
||||
* Process message
|
||||
* Process message.
|
||||
*/
|
||||
private void processMessage(Message message) {
|
||||
LOGGER.info(message.toString());
|
||||
|
@ -24,26 +24,24 @@
|
||||
package com.iluwatar.privateclassdata;
|
||||
|
||||
/**
|
||||
*
|
||||
* The Private Class Data design pattern seeks to reduce exposure of attributes by limiting their
|
||||
* visibility. It reduces the number of class attributes by encapsulating them in single data
|
||||
* object. It allows the class designer to remove write privilege of attributes that are intended to
|
||||
* be set only during construction, even from methods of the target class.
|
||||
* <p>
|
||||
* In the example we have normal {@link Stew} class with some ingredients given in constructor. Then
|
||||
* we have methods to enumerate the ingredients and to taste the stew. The method for tasting the
|
||||
* stew alters the private members of the {@link Stew} class.
|
||||
*
|
||||
* The problem is solved with the Private Class Data pattern. We introduce {@link ImmutableStew}
|
||||
* class that contains {@link StewData}. The private data members of {@link Stew} are now in
|
||||
* {@link StewData} and cannot be altered by {@link ImmutableStew} methods.
|
||||
*
|
||||
* <p>In the example we have normal {@link Stew} class with some ingredients given in constructor.
|
||||
* Then we have methods to enumerate the ingredients and to taste the stew. The method for tasting
|
||||
* the stew alters the private members of the {@link Stew} class.
|
||||
*
|
||||
* <p>The problem is solved with the Private Class Data pattern. We introduce {@link ImmutableStew}
|
||||
* class that contains {@link StewData}. The private data members of {@link Stew} are now in {@link
|
||||
* StewData} and cannot be altered by {@link ImmutableStew} methods.
|
||||
*/
|
||||
public class App {
|
||||
|
||||
/**
|
||||
* Program entry point
|
||||
*
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
@ -27,9 +27,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* Immutable stew class, protected with Private Class Data pattern
|
||||
*
|
||||
* Immutable stew class, protected with Private Class Data pattern.
|
||||
*/
|
||||
public class ImmutableStew {
|
||||
|
||||
@ -42,10 +40,11 @@ public class ImmutableStew {
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix the stew
|
||||
* Mix the stew.
|
||||
*/
|
||||
public void mix() {
|
||||
LOGGER.info("Mixing the immutable stew we find: {} potatoes, {} carrots, {} meat and {} peppers",
|
||||
data.getNumPotatoes(), data.getNumCarrots(), data.getNumMeat(), data.getNumPeppers());
|
||||
LOGGER
|
||||
.info("Mixing the immutable stew we find: {} potatoes, {} carrots, {} meat and {} peppers",
|
||||
data.getNumPotatoes(), data.getNumCarrots(), data.getNumMeat(), data.getNumPeppers());
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* Mutable stew class
|
||||
*
|
||||
* Mutable stew class.
|
||||
*/
|
||||
public class Stew {
|
||||
|
||||
@ -41,7 +39,7 @@ public class Stew {
|
||||
private int numPeppers;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*/
|
||||
public Stew(int numPotatoes, int numCarrots, int numMeat, int numPeppers) {
|
||||
this.numPotatoes = numPotatoes;
|
||||
@ -51,7 +49,7 @@ public class Stew {
|
||||
}
|
||||
|
||||
/**
|
||||
* Mix the stew
|
||||
* Mix the stew.
|
||||
*/
|
||||
public void mix() {
|
||||
LOGGER.info("Mixing the stew we find: {} potatoes, {} carrots, {} meat and {} peppers",
|
||||
@ -59,7 +57,7 @@ public class Stew {
|
||||
}
|
||||
|
||||
/**
|
||||
* Taste the stew
|
||||
* Taste the stew.
|
||||
*/
|
||||
public void taste() {
|
||||
LOGGER.info("Tasting the stew");
|
||||
|
@ -24,9 +24,7 @@
|
||||
package com.iluwatar.privateclassdata;
|
||||
|
||||
/**
|
||||
*
|
||||
* Stew ingredients
|
||||
*
|
||||
* Stew ingredients.
|
||||
*/
|
||||
public class StewData {
|
||||
|
||||
@ -36,7 +34,7 @@ public class StewData {
|
||||
private int numPeppers;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*/
|
||||
public StewData(int numPotatoes, int numCarrots, int numMeat, int numPeppers) {
|
||||
this.numPotatoes = numPotatoes;
|
||||
|
@ -28,25 +28,23 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* The Property pattern is also known as Prototype inheritance.
|
||||
* <p>
|
||||
* In prototype inheritance instead of classes, as opposite to Java class inheritance, objects are
|
||||
* used to create another objects and object hierarchies. Hierarchies are created using prototype
|
||||
* chain through delegation: every object has link to parent object. Any base (parent) object can be
|
||||
* amended at runtime (by adding or removal of some property), and all child objects will be
|
||||
* affected as result.
|
||||
* <p>
|
||||
* In this example we demonstrate {@link Character} instantiation using the Property pattern.
|
||||
*
|
||||
*
|
||||
* <p>In prototype inheritance instead of classes, as opposite to Java class inheritance, objects
|
||||
* are used to create another objects and object hierarchies. Hierarchies are created using
|
||||
* prototype chain through delegation: every object has link to parent object. Any base (parent)
|
||||
* object can be amended at runtime (by adding or removal of some property), and all child objects
|
||||
* will be affected as result.
|
||||
*
|
||||
* <p>In this example we demonstrate {@link Character} instantiation using the Property pattern.
|
||||
*/
|
||||
public class App {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||
|
||||
/**
|
||||
* Program entry point
|
||||
*
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
@ -32,7 +32,7 @@ import java.util.Map;
|
||||
public class Character implements Prototype {
|
||||
|
||||
/**
|
||||
* Enumeration of Character types
|
||||
* Enumeration of Character types.
|
||||
*/
|
||||
public enum Type {
|
||||
WARRIOR, MAGE, ROGUE
|
||||
@ -45,26 +45,28 @@ public class Character implements Prototype {
|
||||
private Type type;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*/
|
||||
public Character() {
|
||||
this.prototype = new Prototype() { // Null-value object
|
||||
@Override
|
||||
public Integer get(Stats stat) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Integer get(Stats stat) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(Stats stat) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean has(Stats stat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Stats stat, Integer val) {}
|
||||
@Override
|
||||
public void set(Stats stat, Integer val) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Stats stat) {}
|
||||
};
|
||||
@Override
|
||||
public void remove(Stats stat) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Character(Type type, Prototype prototype) {
|
||||
@ -73,7 +75,7 @@ public class Character implements Prototype {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*/
|
||||
public Character(String name, Character prototype) {
|
||||
this.name = name;
|
||||
|
@ -24,7 +24,7 @@
|
||||
package com.iluwatar.property;
|
||||
|
||||
/**
|
||||
* Interface for prototype inheritance
|
||||
* Interface for prototype inheritance.
|
||||
*/
|
||||
public interface Prototype {
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
package com.iluwatar.property;
|
||||
|
||||
/**
|
||||
* All possible attributes that Character can have
|
||||
* All possible attributes that Character can have.
|
||||
*/
|
||||
public enum Stats {
|
||||
|
||||
|
@ -27,41 +27,43 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* The Prototype pattern is a creational design pattern in software development. It is used when the
|
||||
* type of objects to create is determined by a prototypical instance, which is cloned to produce
|
||||
* new objects. This pattern is used to: - avoid subclasses of an object creator in the client
|
||||
* application, like the abstract factory pattern does. - avoid the inherent cost of creating a new
|
||||
* object in the standard way (e.g., using the 'new' keyword)
|
||||
* <p>
|
||||
* In this example we have a factory class ({@link HeroFactoryImpl}) producing objects by cloning
|
||||
* the existing ones. The factory's prototype objects are given as constructor parameters.
|
||||
*
|
||||
*
|
||||
* <p>In this example we have a factory class ({@link HeroFactoryImpl}) producing objects by
|
||||
* cloning the existing ones. The factory's prototype objects are given as constructor parameters.
|
||||
*/
|
||||
public class App {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||
|
||||
/**
|
||||
* Program entry point
|
||||
*
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
HeroFactory factory;
|
||||
Mage mage;
|
||||
Warlord warlord;
|
||||
Beast beast;
|
||||
|
||||
factory = new HeroFactoryImpl(new ElfMage("cooking"), new ElfWarlord("cleaning"), new ElfBeast("protecting"));
|
||||
mage = factory.createMage();
|
||||
warlord = factory.createWarlord();
|
||||
beast = factory.createBeast();
|
||||
HeroFactory factory = new HeroFactoryImpl(
|
||||
new ElfMage("cooking"),
|
||||
new ElfWarlord("cleaning"),
|
||||
new ElfBeast("protecting")
|
||||
);
|
||||
Mage mage = factory.createMage();
|
||||
Warlord warlord = factory.createWarlord();
|
||||
Beast beast = factory.createBeast();
|
||||
LOGGER.info(mage.toString());
|
||||
LOGGER.info(warlord.toString());
|
||||
LOGGER.info(beast.toString());
|
||||
|
||||
factory = new HeroFactoryImpl(new OrcMage("axe"), new OrcWarlord("sword"), new OrcBeast("laser"));
|
||||
factory =
|
||||
new HeroFactoryImpl(
|
||||
new OrcMage("axe"),
|
||||
new OrcWarlord("sword"),
|
||||
new OrcBeast("laser")
|
||||
);
|
||||
mage = factory.createMage();
|
||||
warlord = factory.createWarlord();
|
||||
beast = factory.createBeast();
|
||||
|
@ -24,9 +24,7 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* Beast
|
||||
*
|
||||
* Beast.
|
||||
*/
|
||||
public abstract class Beast extends Prototype {
|
||||
|
||||
|
@ -24,12 +24,10 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* ElfBeast
|
||||
*
|
||||
* ElfBeast.
|
||||
*/
|
||||
public class ElfBeast extends Beast {
|
||||
|
||||
|
||||
private String helpType;
|
||||
|
||||
public ElfBeast(String helpType) {
|
||||
|
@ -24,15 +24,13 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* ElfMage
|
||||
*
|
||||
* ElfMage.
|
||||
*/
|
||||
public class ElfMage extends Mage {
|
||||
|
||||
|
||||
|
||||
private String helpType;
|
||||
|
||||
|
||||
public ElfMage(String helpType) {
|
||||
this.helpType = helpType;
|
||||
}
|
||||
|
@ -24,14 +24,12 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* ElfWarlord
|
||||
*
|
||||
* ElfWarlord.
|
||||
*/
|
||||
public class ElfWarlord extends Warlord {
|
||||
|
||||
private String helpType;
|
||||
|
||||
|
||||
public ElfWarlord(String helpType) {
|
||||
this.helpType = helpType;
|
||||
}
|
||||
|
@ -24,9 +24,7 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* Interface for the factory class.
|
||||
*
|
||||
*/
|
||||
public interface HeroFactory {
|
||||
|
||||
|
@ -24,9 +24,7 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* Concrete factory class.
|
||||
*
|
||||
*/
|
||||
public class HeroFactoryImpl implements HeroFactory {
|
||||
|
||||
@ -35,7 +33,7 @@ public class HeroFactoryImpl implements HeroFactory {
|
||||
private Beast beast;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Constructor.
|
||||
*/
|
||||
public HeroFactoryImpl(Mage mage, Warlord warlord, Beast beast) {
|
||||
this.mage = mage;
|
||||
@ -44,7 +42,7 @@ public class HeroFactoryImpl implements HeroFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create mage
|
||||
* Create mage.
|
||||
*/
|
||||
public Mage createMage() {
|
||||
try {
|
||||
@ -55,7 +53,7 @@ public class HeroFactoryImpl implements HeroFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create warlord
|
||||
* Create warlord.
|
||||
*/
|
||||
public Warlord createWarlord() {
|
||||
try {
|
||||
@ -66,7 +64,7 @@ public class HeroFactoryImpl implements HeroFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create beast
|
||||
* Create beast.
|
||||
*/
|
||||
public Beast createBeast() {
|
||||
try {
|
||||
|
@ -24,9 +24,7 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* Mage
|
||||
*
|
||||
* Mage.
|
||||
*/
|
||||
public abstract class Mage extends Prototype {
|
||||
|
||||
|
@ -24,18 +24,16 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* OrcBeast
|
||||
*
|
||||
* OrcBeast.
|
||||
*/
|
||||
public class OrcBeast extends Beast {
|
||||
|
||||
|
||||
private String weapon;
|
||||
|
||||
public OrcBeast(String weapon) {
|
||||
this.weapon = weapon;
|
||||
}
|
||||
|
||||
|
||||
public OrcBeast(OrcBeast orcBeast) {
|
||||
this.weapon = orcBeast.weapon;
|
||||
}
|
||||
@ -49,6 +47,6 @@ public class OrcBeast extends Beast {
|
||||
public String toString() {
|
||||
return "Orcish wolf attacks with " + weapon;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -24,9 +24,7 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* OrcMage
|
||||
*
|
||||
* OrcMage.
|
||||
*/
|
||||
public class OrcMage extends Mage {
|
||||
|
||||
@ -35,7 +33,7 @@ public class OrcMage extends Mage {
|
||||
public OrcMage(String weapon) {
|
||||
this.weapon = weapon;
|
||||
}
|
||||
|
||||
|
||||
public OrcMage(OrcMage orcMage) {
|
||||
this.weapon = orcMage.weapon;
|
||||
}
|
||||
|
@ -24,9 +24,7 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* OrcWarlord
|
||||
*
|
||||
* OrcWarlord.
|
||||
*/
|
||||
public class OrcWarlord extends Warlord {
|
||||
|
||||
@ -35,7 +33,7 @@ public class OrcWarlord extends Warlord {
|
||||
public OrcWarlord(String weapon) {
|
||||
this.weapon = weapon;
|
||||
}
|
||||
|
||||
|
||||
public OrcWarlord(OrcWarlord orcWarlord) {
|
||||
this.weapon = orcWarlord.weapon;
|
||||
}
|
||||
|
@ -24,9 +24,7 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* Prototype
|
||||
*
|
||||
* Prototype.
|
||||
*/
|
||||
public abstract class Prototype implements Cloneable {
|
||||
|
||||
|
@ -24,9 +24,7 @@
|
||||
package com.iluwatar.prototype;
|
||||
|
||||
/**
|
||||
*
|
||||
* Warlord
|
||||
*
|
||||
* Warlord.
|
||||
*/
|
||||
public abstract class Warlord extends Prototype {
|
||||
|
||||
|
@ -24,25 +24,23 @@
|
||||
package com.iluwatar.proxy;
|
||||
|
||||
/**
|
||||
*
|
||||
* A proxy, in its most general form, is a class functioning as an interface to something else. The
|
||||
* proxy could interface to anything: a network connection, a large object in memory, a file, or
|
||||
* some other resource that is expensive or impossible to duplicate. In short, a proxy is a wrapper
|
||||
* or agent object that is being called by the client to access the real serving object behind the
|
||||
* scenes.
|
||||
* <p>
|
||||
* The Proxy design pattern allows you to provide an interface to other objects by creating a
|
||||
*
|
||||
* <p>The Proxy design pattern allows you to provide an interface to other objects by creating a
|
||||
* wrapper class as the proxy. The wrapper class, which is the proxy, can add additional
|
||||
* functionality to the object of interest without changing the object's code.
|
||||
* <p>
|
||||
* In this example the proxy ({@link WizardTowerProxy}) controls access to the actual object (
|
||||
*
|
||||
* <p>In this example the proxy ({@link WizardTowerProxy}) controls access to the actual object (
|
||||
* {@link IvoryTower}).
|
||||
*
|
||||
*/
|
||||
public class App {
|
||||
|
||||
/**
|
||||
* Program entry point
|
||||
* Program entry point.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
@ -27,9 +27,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* The object to be proxyed.
|
||||
*
|
||||
*/
|
||||
public class IvoryTower implements WizardTower {
|
||||
|
||||
|
@ -24,9 +24,7 @@
|
||||
package com.iluwatar.proxy;
|
||||
|
||||
/**
|
||||
*
|
||||
* Wizard
|
||||
*
|
||||
* Wizard.
|
||||
*/
|
||||
public class Wizard {
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
package com.iluwatar.proxy;
|
||||
|
||||
/**
|
||||
* WizardTower interface
|
||||
* WizardTower interface.
|
||||
*/
|
||||
public interface WizardTower {
|
||||
|
||||
|
@ -27,9 +27,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* The proxy controlling access to the {@link IvoryTower}.
|
||||
*
|
||||
*/
|
||||
public class WizardTowerProxy implements WizardTower {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user