This commit is contained in:
Ilkka Seppälä 2019-11-16 14:56:36 +02:00
commit 9e58edf05e
56 changed files with 281 additions and 313 deletions

View File

@ -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);
}

View File

@ -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()) {

View File

@ -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

View File

@ -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}
*/

View File

@ -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");

View File

@ -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
*/

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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) {
/*

View File

@ -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;
}

View File

@ -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
*/

View File

@ -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
*/

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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) {

View File

@ -65,7 +65,7 @@ public interface Message {
};
/**
* Enumeration of Type of Headers
* Enumeration of Type of Headers.
*/
enum Headers {
DATE, SENDER

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -24,7 +24,7 @@
package com.iluwatar.priority.queue;
/**
* Message bean
* Message bean.
*/
public class Message implements Comparable<Message> {
private final String message;

View File

@ -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;

View File

@ -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()) {

View File

@ -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());

View File

@ -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) {

View File

@ -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());
}
}

View File

@ -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");

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -24,7 +24,7 @@
package com.iluwatar.property;
/**
* Interface for prototype inheritance
* Interface for prototype inheritance.
*/
public interface Prototype {

View File

@ -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 {

View File

@ -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();

View File

@ -24,9 +24,7 @@
package com.iluwatar.prototype;
/**
*
* Beast
*
* Beast.
*/
public abstract class Beast extends Prototype {

View File

@ -24,12 +24,10 @@
package com.iluwatar.prototype;
/**
*
* ElfBeast
*
* ElfBeast.
*/
public class ElfBeast extends Beast {
private String helpType;
public ElfBeast(String helpType) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -24,9 +24,7 @@
package com.iluwatar.prototype;
/**
*
* Interface for the factory class.
*
*/
public interface HeroFactory {

View File

@ -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 {

View File

@ -24,9 +24,7 @@
package com.iluwatar.prototype;
/**
*
* Mage
*
* Mage.
*/
public abstract class Mage extends Prototype {

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -24,9 +24,7 @@
package com.iluwatar.prototype;
/**
*
* Prototype
*
* Prototype.
*/
public abstract class Prototype implements Cloneable {

View File

@ -24,9 +24,7 @@
package com.iluwatar.prototype;
/**
*
* Warlord
*
* Warlord.
*/
public abstract class Warlord extends Prototype {

View File

@ -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) {

View File

@ -27,9 +27,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* The object to be proxyed.
*
*/
public class IvoryTower implements WizardTower {

View File

@ -24,9 +24,7 @@
package com.iluwatar.proxy;
/**
*
* Wizard
*
* Wizard.
*/
public class Wizard {

View File

@ -24,7 +24,7 @@
package com.iluwatar.proxy;
/**
* WizardTower interface
* WizardTower interface.
*/
public interface WizardTower {

View File

@ -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 {