Resolves checkstyle errors for remaining m (#1090)
* Reduces checkstyle errors in marker * Reduces checkstyle errors in master-worker-pattern * Reduces checkstyle errors in mediator * Reduces checkstyle errors in memento * Reduces checkstyle errors in model-view-controller * Reduces checkstyle errors in model-view-presenter * Reduces checkstyle errors in module * Reduces checkstyle errors in monad * Reduces checkstyle errors in monostate * Reduces checkstyle errors in multiton * Reduces checkstyle errors in mute-idiom * Reduces checkstyle errors in mutex
This commit is contained in:
parent
3ccc9baa1a
commit
1fdc650545
@ -25,27 +25,23 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Alexis on 28-Apr-17.
|
* Created by Alexis on 28-Apr-17. With Marker interface idea is to make empty interface and extend
|
||||||
* With Marker interface idea is to make empty interface and extend it.
|
* it. Basically it is just to identify the special objects from normal objects. Like in case of
|
||||||
* Basically it is just to identify the special objects from normal objects.
|
* serialization , objects that need to be serialized must implement serializable interface (it is
|
||||||
* Like in case of serialization , objects that need to be serialized must implement serializable interface
|
* empty interface) and down the line writeObject() method must be checking if it is a instance of
|
||||||
* (it is empty interface) and down the line writeObject() method must be checking
|
* serializable or not.
|
||||||
* if it is a instance of serializable or not.
|
*
|
||||||
* <p>
|
* <p>Marker interface vs annotation Marker interfaces and marker annotations both have their uses,
|
||||||
* Marker interface vs annotation
|
* neither of them is obsolete or always better then the other one. If you want to define a type
|
||||||
* Marker interfaces and marker annotations both have their uses,
|
* that does not have any new methods associated with it, a marker interface is the way to go. If
|
||||||
* neither of them is obsolete or always better then the other one.
|
* you want to mark program elements other than classes and interfaces, to allow for the possibility
|
||||||
* If you want to define a type that does not have any new methods associated with it,
|
* of adding more information to the marker in the future, or to fit the marker into a framework
|
||||||
* a marker interface is the way to go.
|
* that already makes heavy use of annotation types, then a marker annotation is the correct choice
|
||||||
* If you want to mark program elements other than classes and interfaces,
|
|
||||||
* to allow for the possibility of adding more information to the marker in the future,
|
|
||||||
* or to fit the marker into a framework that already makes heavy use of annotation types,
|
|
||||||
* then a marker annotation is the correct choice
|
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point.
|
||||||
*
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
|
@ -25,7 +25,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class defining Guard
|
* Class defining Guard.
|
||||||
*/
|
*/
|
||||||
public class Guard implements Permission {
|
public class Guard implements Permission {
|
||||||
|
|
||||||
|
@ -22,8 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface without any methods
|
* Interface without any methods Marker interface is based on that assumption.
|
||||||
* Marker interface is based on that assumption
|
|
||||||
*/
|
*/
|
||||||
public interface Permission {
|
public interface Permission {
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class defining Thief
|
* Class defining Thief.
|
||||||
*/
|
*/
|
||||||
public class Thief {
|
public class Thief {
|
||||||
|
|
||||||
|
@ -28,30 +28,37 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>The <b><em>Master-Worker</em></b> pattern is used when the problem at hand can be solved by dividing into
|
* <p>The <b><em>Master-Worker</em></b> pattern is used when the problem at hand can be solved by
|
||||||
* multiple parts which need to go through the same computation and may need to be aggregated to get final result.
|
* dividing into
|
||||||
* Parallel processing is performed using a system consisting of a master and some number of workers, where a
|
* multiple parts which need to go through the same computation and may need to be aggregated to get
|
||||||
* master divides the work among the workers, gets the result back from them and assimilates all the results to
|
* final result. Parallel processing is performed using a system consisting of a master and some
|
||||||
* give final result. The only communication is between the master and the worker - none of the workers communicate
|
* number of workers, where a master divides the work among the workers, gets the result back from
|
||||||
* among one another and the user only communicates with the master to get required job done.</p>
|
* them and assimilates all the results to give final result. The only communication is between the
|
||||||
* <p>In our example, we have generic abstract classes {@link MasterWorker}, {@link Master} and {@link Worker} which
|
* master and the worker - none of the workers communicate among one another and the user only
|
||||||
* have to be extended by the classes which will perform the specific job at hand (in this case finding transpose of
|
* communicates with the master to get required job done.</p>
|
||||||
* matrix, done by {@link ArrayTransposeMasterWorker}, {@link ArrayTransposeMaster} and {@link ArrayTransposeWorker}).
|
* <p>In our example, we have generic abstract classes {@link MasterWorker}, {@link Master} and
|
||||||
* The Master class divides the work into parts to be given to the workers, collects the results from the workers and
|
* {@link Worker} which
|
||||||
* aggregates it when all workers have responded before returning the solution. The Worker class extends the Thread
|
* have to be extended by the classes which will perform the specific job at hand (in this case
|
||||||
* class to enable parallel processing, and does the work once the data has been received from the Master. The
|
* finding transpose of matrix, done by {@link ArrayTransposeMasterWorker}, {@link
|
||||||
* MasterWorker contains a reference to the Master class, gets the input from the App and passes it on to the Master.
|
* ArrayTransposeMaster} and {@link ArrayTransposeWorker}). The Master class divides the work into
|
||||||
* These 3 classes define the system which computes the result. We also have 2 abstract classes {@link Input} and
|
* parts to be given to the workers, collects the results from the workers and aggregates it when
|
||||||
* {@link Result}, which contain the input data and result data respectively. The Input class also has an abstract
|
* all workers have responded before returning the solution. The Worker class extends the Thread
|
||||||
* method divideData which defines how the data is to be divided into segments. These classes are extended by
|
* class to enable parallel processing, and does the work once the data has been received from the
|
||||||
* {@link ArrayInput} and {@link ArrayResult}.</p>
|
* Master. The MasterWorker contains a reference to the Master class, gets the input from the App
|
||||||
|
* and passes it on to the Master. These 3 classes define the system which computes the result. We
|
||||||
|
* also have 2 abstract classes {@link Input} and {@link Result}, which contain the input data and
|
||||||
|
* result data respectively. The Input class also has an abstract method divideData which defines
|
||||||
|
* how the data is to be divided into segments. These classes are extended by {@link ArrayInput} and
|
||||||
|
* {@link ArrayResult}.</p>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -59,9 +66,9 @@ public class App {
|
|||||||
ArrayTransposeMasterWorker mw = new ArrayTransposeMasterWorker();
|
ArrayTransposeMasterWorker mw = new ArrayTransposeMasterWorker();
|
||||||
int rows = 10;
|
int rows = 10;
|
||||||
int columns = 20;
|
int columns = 20;
|
||||||
int[][] inputMatrix = ArrayUtilityMethods.createRandomIntMatrix(rows,columns);
|
int[][] inputMatrix = ArrayUtilityMethods.createRandomIntMatrix(rows, columns);
|
||||||
ArrayInput input = new ArrayInput(inputMatrix);
|
ArrayInput input = new ArrayInput(inputMatrix);
|
||||||
ArrayResult result = (ArrayResult) mw.getResult(input);
|
ArrayResult result = (ArrayResult) mw.getResult(input);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
ArrayUtilityMethods.printMatrix(inputMatrix);
|
ArrayUtilityMethods.printMatrix(inputMatrix);
|
||||||
ArrayUtilityMethods.printMatrix(result.data);
|
ArrayUtilityMethods.printMatrix(result.data);
|
||||||
|
@ -27,8 +27,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Class ArrayInput extends abstract class {@link Input} and contains data
|
* Class ArrayInput extends abstract class {@link Input} and contains data of type int[][].
|
||||||
*of type int[][].
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ArrayInput extends Input<int[][]> {
|
public class ArrayInput extends Input<int[][]> {
|
||||||
@ -36,7 +35,7 @@ public class ArrayInput extends Input<int[][]> {
|
|||||||
public ArrayInput(int[][] data) {
|
public ArrayInput(int[][] data) {
|
||||||
super(data);
|
super(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int[] makeDivisions(int[][] data, int num) {
|
static int[] makeDivisions(int[][] data, int num) {
|
||||||
int initialDivision = data.length / num; //equally dividing
|
int initialDivision = data.length / num; //equally dividing
|
||||||
int[] divisions = new int[num];
|
int[] divisions = new int[num];
|
||||||
@ -81,6 +80,6 @@ public class ArrayInput extends Input<int[][]> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,7 @@
|
|||||||
package com.iluwatar.masterworker;
|
package com.iluwatar.masterworker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Class ArrayResult extends abstract class {@link Result} and contains data
|
* Class ArrayResult extends abstract class {@link Result} and contains data of type int[][].
|
||||||
*of type int[][].
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ArrayResult extends Result<int[][]> {
|
public class ArrayResult extends Result<int[][]> {
|
||||||
|
@ -23,23 +23,23 @@
|
|||||||
|
|
||||||
package com.iluwatar.masterworker;
|
package com.iluwatar.masterworker;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Class ArrayUtilityMethods has some utility methods for matrices and arrays.
|
* Class ArrayUtilityMethods has some utility methods for matrices and arrays.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ArrayUtilityMethods {
|
public class ArrayUtilityMethods {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ArrayUtilityMethods.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(ArrayUtilityMethods.class);
|
||||||
|
|
||||||
private static final Random RANDOM = new Random();
|
private static final Random RANDOM = new Random();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method arraysSame compares 2 arrays @param a1 and @param a2
|
* Method arraysSame compares 2 arrays @param a1 and @param a2 and @return whether their values
|
||||||
* and @return whether their values are equal (boolean).
|
* are equal (boolean).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static boolean arraysSame(int[] a1, int[] a2) {
|
public static boolean arraysSame(int[] a1, int[] a2) {
|
||||||
@ -61,10 +61,10 @@ public class ArrayUtilityMethods {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method matricesSame compares 2 matrices @param m1 and @param m2
|
* Method matricesSame compares 2 matrices @param m1 and @param m2 and @return whether their
|
||||||
* and @return whether their values are equal (boolean).
|
* values are equal (boolean).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static boolean matricesSame(int[][] m1, int[][] m2) {
|
public static boolean matricesSame(int[][] m1, int[][] m2) {
|
||||||
if (m1.length != m2.length) {
|
if (m1.length != m2.length) {
|
||||||
return false;
|
return false;
|
||||||
@ -81,12 +81,12 @@ public class ArrayUtilityMethods {
|
|||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method createRandomIntMatrix creates a random matrix of size @param rows
|
* Method createRandomIntMatrix creates a random matrix of size @param rows and @param columns.
|
||||||
* and @param columns @return it (int[][]).
|
*
|
||||||
|
* @return it (int[][]).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static int[][] createRandomIntMatrix(int rows, int columns) {
|
public static int[][] createRandomIntMatrix(int rows, int columns) {
|
||||||
int[][] matrix = new int[rows][columns];
|
int[][] matrix = new int[rows][columns];
|
||||||
for (int i = 0; i < rows; i++) {
|
for (int i = 0; i < rows; i++) {
|
||||||
@ -97,11 +97,11 @@ public class ArrayUtilityMethods {
|
|||||||
}
|
}
|
||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method printMatrix prints input matrix @param matrix.
|
* Method printMatrix prints input matrix @param matrix.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static void printMatrix(int[][] matrix) {
|
public static void printMatrix(int[][] matrix) {
|
||||||
//prints out int[][]
|
//prints out int[][]
|
||||||
for (int i = 0; i < matrix.length; i++) {
|
for (int i = 0; i < matrix.length; i++) {
|
||||||
@ -111,5 +111,5 @@ public class ArrayUtilityMethods {
|
|||||||
LOGGER.info("");
|
LOGGER.info("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,18 +26,19 @@ package com.iluwatar.masterworker;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*The abstract Input class, having 1 public field which contains input data,
|
* The abstract Input class, having 1 public field which contains input data, and abstract method
|
||||||
*and abstract method divideData.
|
* divideData.
|
||||||
|
*
|
||||||
* @param <T> T will be type of data.
|
* @param <T> T will be type of data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class Input<T> {
|
public abstract class Input<T> {
|
||||||
|
|
||||||
public final T data;
|
public final T data;
|
||||||
|
|
||||||
public Input(T data) {
|
public Input(T data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract ArrayList<Input> divideData(int num);
|
public abstract ArrayList<Input> divideData(int num);
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,13 @@
|
|||||||
package com.iluwatar.masterworker;
|
package com.iluwatar.masterworker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*The abstract Result class, which contains 1 public field containing result
|
* The abstract Result class, which contains 1 public field containing result data.
|
||||||
*data.
|
*
|
||||||
* @param <T> T will be type of data.
|
* @param <T> T will be type of data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class Result<T> {
|
public abstract class Result<T> {
|
||||||
|
|
||||||
public final T data;
|
public final T data;
|
||||||
|
|
||||||
public Result(T data) {
|
public Result(T data) {
|
||||||
|
@ -27,8 +27,8 @@ import com.iluwatar.masterworker.system.systemmaster.ArrayTransposeMaster;
|
|||||||
import com.iluwatar.masterworker.system.systemmaster.Master;
|
import com.iluwatar.masterworker.system.systemmaster.Master;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Class ArrayTransposeMasterWorker extends abstract class {@link MasterWorker} and
|
* Class ArrayTransposeMasterWorker extends abstract class {@link MasterWorker} and specifically
|
||||||
*specifically solves the problem of finding transpose of input array.
|
* solves the problem of finding transpose of input array.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ArrayTransposeMasterWorker extends MasterWorker {
|
public class ArrayTransposeMasterWorker extends MasterWorker {
|
||||||
|
@ -28,7 +28,7 @@ import com.iluwatar.masterworker.Result;
|
|||||||
import com.iluwatar.masterworker.system.systemmaster.Master;
|
import com.iluwatar.masterworker.system.systemmaster.Master;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*The abstract MasterWorker class which contains reference to master.
|
* The abstract MasterWorker class which contains reference to master.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class MasterWorker {
|
public abstract class MasterWorker {
|
||||||
|
@ -23,16 +23,15 @@
|
|||||||
|
|
||||||
package com.iluwatar.masterworker.system.systemmaster;
|
package com.iluwatar.masterworker.system.systemmaster;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import com.iluwatar.masterworker.ArrayResult;
|
import com.iluwatar.masterworker.ArrayResult;
|
||||||
import com.iluwatar.masterworker.system.systemworkers.ArrayTransposeWorker;
|
import com.iluwatar.masterworker.system.systemworkers.ArrayTransposeWorker;
|
||||||
import com.iluwatar.masterworker.system.systemworkers.Worker;
|
import com.iluwatar.masterworker.system.systemworkers.Worker;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Class ArrayTransposeMaster extends abstract class {@link Master} and contains
|
* Class ArrayTransposeMaster extends abstract class {@link Master} and contains definition of
|
||||||
*definition of aggregateData, which will obtain final result from all
|
* aggregateData, which will obtain final result from all data obtained and for setWorkers.
|
||||||
*data obtained and for setWorkers.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ArrayTransposeMaster extends Master {
|
public class ArrayTransposeMaster extends Master {
|
||||||
@ -43,26 +42,29 @@ public class ArrayTransposeMaster extends Master {
|
|||||||
@Override
|
@Override
|
||||||
ArrayList<Worker> setWorkers(int num) {
|
ArrayList<Worker> setWorkers(int num) {
|
||||||
ArrayList<Worker> ws = new ArrayList<Worker>(num);
|
ArrayList<Worker> ws = new ArrayList<Worker>(num);
|
||||||
for (int i = 0; i < num ; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
ws.add(new ArrayTransposeWorker(this, i + 1));
|
ws.add(new ArrayTransposeWorker(this, i + 1));
|
||||||
//i+1 will be id
|
//i+1 will be id
|
||||||
}
|
}
|
||||||
return ws;
|
return ws;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
ArrayResult aggregateData() {
|
ArrayResult aggregateData() {
|
||||||
//number of rows in final result is number of rows in any of obtained results obtained from workers
|
// number of rows in final result is number of rows in any of obtained results from workers
|
||||||
int rows = ((ArrayResult) this.getAllResultData().get(this.getAllResultData().keys().nextElement())).data.length;
|
int rows = ((ArrayResult) this.getAllResultData()
|
||||||
int columns = 0; //number of columns is sum of number of columns in all results obtained from workers
|
.get(this.getAllResultData().keys().nextElement())).data.length;
|
||||||
for (Enumeration<Integer> e = this.getAllResultData().keys(); e.hasMoreElements();) {
|
int columns =
|
||||||
|
0; //number of columns is sum of number of columns in all results obtained from workers
|
||||||
|
for (Enumeration<Integer> e = this.getAllResultData().keys(); e.hasMoreElements(); ) {
|
||||||
columns += ((ArrayResult) this.getAllResultData().get(e.nextElement())).data[0].length;
|
columns += ((ArrayResult) this.getAllResultData().get(e.nextElement())).data[0].length;
|
||||||
}
|
}
|
||||||
int[][] resultData = new int[rows][columns];
|
int[][] resultData = new int[rows][columns];
|
||||||
int columnsDone = 0; //columns aggregated so far
|
int columnsDone = 0; //columns aggregated so far
|
||||||
for (int i = 0; i < this.getExpectedNumResults(); i++) {
|
for (int i = 0; i < this.getExpectedNumResults(); i++) {
|
||||||
//result obtained from ith worker
|
//result obtained from ith worker
|
||||||
int[][] work = ((ArrayResult) this.getAllResultData().get(this.getWorkers().get(i).getWorkerId())).data;
|
int[][] work =
|
||||||
|
((ArrayResult) this.getAllResultData().get(this.getWorkers().get(i).getWorkerId())).data;
|
||||||
for (int m = 0; m < work.length; m++) {
|
for (int m = 0; m < work.length; m++) {
|
||||||
//m = row number, n = columns number
|
//m = row number, n = columns number
|
||||||
for (int n = 0; n < work[0].length; n++) {
|
for (int n = 0; n < work[0].length; n++) {
|
||||||
@ -73,5 +75,5 @@ public class ArrayTransposeMaster extends Master {
|
|||||||
}
|
}
|
||||||
return new ArrayResult(resultData);
|
return new ArrayResult(resultData);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,18 +23,17 @@
|
|||||||
|
|
||||||
package com.iluwatar.masterworker.system.systemmaster;
|
package com.iluwatar.masterworker.system.systemmaster;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import com.iluwatar.masterworker.Input;
|
import com.iluwatar.masterworker.Input;
|
||||||
import com.iluwatar.masterworker.Result;
|
import com.iluwatar.masterworker.Result;
|
||||||
import com.iluwatar.masterworker.system.systemworkers.Worker;
|
import com.iluwatar.masterworker.system.systemworkers.Worker;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*The abstract Master class which contains private fields numOfWorkers
|
* The abstract Master class which contains private fields numOfWorkers (number of workers), workers
|
||||||
*(number of workers), workers (arraylist of workers), expectedNumResults
|
* (arraylist of workers), expectedNumResults (number of divisions of input data, same as expected
|
||||||
*(number of divisions of input data, same as expected number of results),
|
* number of results), allResultData (hashtable of results obtained from workers, mapped by their
|
||||||
*allResultData (hashtable of results obtained from workers, mapped by
|
* ids) and finalResult (aggregated from allResultData).
|
||||||
*their ids) and finalResult (aggregated from allResultData).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class Master {
|
public abstract class Master {
|
||||||
@ -43,7 +42,7 @@ public abstract class Master {
|
|||||||
private int expectedNumResults;
|
private int expectedNumResults;
|
||||||
private Hashtable<Integer, Result> allResultData;
|
private Hashtable<Integer, Result> allResultData;
|
||||||
private Result finalResult;
|
private Result finalResult;
|
||||||
|
|
||||||
Master(int numOfWorkers) {
|
Master(int numOfWorkers) {
|
||||||
this.numOfWorkers = numOfWorkers;
|
this.numOfWorkers = numOfWorkers;
|
||||||
this.workers = setWorkers(numOfWorkers);
|
this.workers = setWorkers(numOfWorkers);
|
||||||
@ -51,46 +50,46 @@ public abstract class Master {
|
|||||||
this.allResultData = new Hashtable<Integer, Result>(numOfWorkers);
|
this.allResultData = new Hashtable<Integer, Result>(numOfWorkers);
|
||||||
this.finalResult = null;
|
this.finalResult = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result getFinalResult() {
|
public Result getFinalResult() {
|
||||||
return this.finalResult;
|
return this.finalResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hashtable<Integer, Result> getAllResultData() {
|
Hashtable<Integer, Result> getAllResultData() {
|
||||||
return this.allResultData;
|
return this.allResultData;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getExpectedNumResults() {
|
int getExpectedNumResults() {
|
||||||
return this.expectedNumResults;
|
return this.expectedNumResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<Worker> getWorkers() {
|
ArrayList<Worker> getWorkers() {
|
||||||
return this.workers;
|
return this.workers;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract ArrayList<Worker> setWorkers(int num);
|
abstract ArrayList<Worker> setWorkers(int num);
|
||||||
|
|
||||||
public void doWork(Input input) {
|
public void doWork(Input input) {
|
||||||
divideWork(input);
|
divideWork(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void divideWork(Input input) {
|
private void divideWork(Input input) {
|
||||||
ArrayList<Input> dividedInput = input.divideData(numOfWorkers);
|
ArrayList<Input> dividedInput = input.divideData(numOfWorkers);
|
||||||
if (dividedInput != null) {
|
if (dividedInput != null) {
|
||||||
this.expectedNumResults = dividedInput.size();
|
this.expectedNumResults = dividedInput.size();
|
||||||
for (int i = 0; i < this.expectedNumResults; i++) {
|
for (int i = 0; i < this.expectedNumResults; i++) {
|
||||||
//ith division given to ith worker in this.workers
|
//ith division given to ith worker in this.workers
|
||||||
this.workers.get(i).setReceivedData(this, dividedInput.get(i));
|
this.workers.get(i).setReceivedData(this, dividedInput.get(i));
|
||||||
this.workers.get(i).run();
|
this.workers.get(i).run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveData(Result data, Worker w) {
|
public void receiveData(Result data, Worker w) {
|
||||||
//check if can receive..if yes:
|
//check if can receive..if yes:
|
||||||
collectResult(data, w.getWorkerId());
|
collectResult(data, w.getWorkerId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectResult(Result data, int workerId) {
|
private void collectResult(Result data, int workerId) {
|
||||||
this.allResultData.put(workerId, data);
|
this.allResultData.put(workerId, data);
|
||||||
if (this.allResultData.size() == this.expectedNumResults) {
|
if (this.allResultData.size() == this.expectedNumResults) {
|
||||||
@ -98,6 +97,6 @@ public abstract class Master {
|
|||||||
this.finalResult = aggregateData();
|
this.finalResult = aggregateData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract Result aggregateData();
|
abstract Result aggregateData();
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,8 @@ import com.iluwatar.masterworker.ArrayResult;
|
|||||||
import com.iluwatar.masterworker.system.systemmaster.Master;
|
import com.iluwatar.masterworker.system.systemmaster.Master;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*Class ArrayTransposeWorker extends abstract class {@link Worker} and defines method
|
* Class ArrayTransposeWorker extends abstract class {@link Worker} and defines method
|
||||||
*executeOperation(), to be performed on data received from master.
|
* executeOperation(), to be performed on data received from master.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ArrayTransposeWorker extends Worker {
|
public class ArrayTransposeWorker extends Worker {
|
||||||
@ -41,12 +41,14 @@ public class ArrayTransposeWorker extends Worker {
|
|||||||
@Override
|
@Override
|
||||||
ArrayResult executeOperation() {
|
ArrayResult executeOperation() {
|
||||||
//number of rows in result matrix is equal to number of columns in input matrix and vice versa
|
//number of rows in result matrix is equal to number of columns in input matrix and vice versa
|
||||||
int[][] resultData = new int[((ArrayInput) this.getReceivedData()).data[0].length]
|
ArrayInput arrayInput = (ArrayInput) this.getReceivedData();
|
||||||
[((ArrayInput) this.getReceivedData()).data.length];
|
final int rows = arrayInput.data[0].length;
|
||||||
for (int i = 0; i < ((ArrayInput) this.getReceivedData()).data.length; i++) {
|
final int cols = arrayInput.data.length;
|
||||||
for (int j = 0; j < ((ArrayInput) this.getReceivedData()).data[0].length; j++) {
|
int[][] resultData = new int[rows][cols];
|
||||||
|
for (int i = 0; i < cols; i++) {
|
||||||
|
for (int j = 0; j < rows; j++) {
|
||||||
//flipping element positions along diagonal
|
//flipping element positions along diagonal
|
||||||
resultData[j][i] = ((ArrayInput) this.getReceivedData()).data[i][j];
|
resultData[j][i] = arrayInput.data[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ArrayResult(resultData);
|
return new ArrayResult(resultData);
|
||||||
|
@ -28,9 +28,8 @@ import com.iluwatar.masterworker.Result;
|
|||||||
import com.iluwatar.masterworker.system.systemmaster.Master;
|
import com.iluwatar.masterworker.system.systemmaster.Master;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*The abstract Worker class which extends Thread class to enable parallel
|
* The abstract Worker class which extends Thread class to enable parallel processing. Contains
|
||||||
*processing. Contains fields master(holding reference to master), workerId
|
* fields master(holding reference to master), workerId (unique id) and receivedData(from master).
|
||||||
*(unique id) and receivedData(from master).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class Worker extends Thread {
|
public abstract class Worker extends Thread {
|
||||||
@ -61,7 +60,7 @@ public abstract class Worker extends Thread {
|
|||||||
|
|
||||||
private void sendToMaster(Result data) {
|
private void sendToMaster(Result data) {
|
||||||
this.master.receiveData(data, this);
|
this.master.receiveData(data, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() { //from Thread class
|
public void run() { //from Thread class
|
||||||
Result work = executeOperation();
|
Result work = executeOperation();
|
||||||
|
@ -24,15 +24,15 @@
|
|||||||
package com.iluwatar.mediator;
|
package com.iluwatar.mediator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Action enumeration.
|
* Action enumeration.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public enum Action {
|
public enum Action {
|
||||||
|
|
||||||
HUNT("hunted a rabbit", "arrives for dinner"), TALE("tells a tale", "comes to listen"), GOLD(
|
HUNT("hunted a rabbit", "arrives for dinner"),
|
||||||
"found gold", "takes his share of the gold"), ENEMY("spotted enemies", "runs for cover"), NONE(
|
TALE("tells a tale", "comes to listen"),
|
||||||
"", "");
|
GOLD("found gold", "takes his share of the gold"),
|
||||||
|
ENEMY("spotted enemies", "runs for cover"),
|
||||||
|
NONE("", "");
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
private String description;
|
private String description;
|
||||||
|
@ -24,32 +24,31 @@
|
|||||||
package com.iluwatar.mediator;
|
package com.iluwatar.mediator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* The Mediator pattern defines an object that encapsulates how a set of objects interact. This
|
* The Mediator pattern defines an object that encapsulates how a set of objects interact. This
|
||||||
* pattern is considered to be a behavioral pattern due to the way it can alter the program's
|
* pattern is considered to be a behavioral pattern due to the way it can alter the program's
|
||||||
* running behavior.
|
* running behavior.
|
||||||
* <p>
|
*
|
||||||
* Usually a program is made up of a large number of classes. So the logic and computation is
|
* <p>Usually a program is made up of a large number of classes. So the logic and computation is
|
||||||
* distributed among these classes. However, as more classes are developed in a program, especially
|
* distributed among these classes. However, as more classes are developed in a program, especially
|
||||||
* during maintenance and/or refactoring, the problem of communication between these classes may
|
* during maintenance and/or refactoring, the problem of communication between these classes may
|
||||||
* become more complex. This makes the program harder to read and maintain. Furthermore, it can
|
* become more complex. This makes the program harder to read and maintain. Furthermore, it can
|
||||||
* become difficult to change the program, since any change may affect code in several other
|
* become difficult to change the program, since any change may affect code in several other
|
||||||
* classes.
|
* classes.
|
||||||
* <p>
|
*
|
||||||
* With the Mediator pattern, communication between objects is encapsulated with a mediator object.
|
* <p>With the Mediator pattern, communication between objects is encapsulated with a mediator
|
||||||
* Objects no longer communicate directly with each other, but instead communicate through the
|
* object. Objects no longer communicate directly with each other, but instead communicate through
|
||||||
* mediator. This reduces the dependencies between communicating objects, thereby lowering the
|
* the mediator. This reduces the dependencies between communicating objects, thereby lowering the
|
||||||
* coupling.
|
* coupling.
|
||||||
* <p>
|
*
|
||||||
* In this example the mediator encapsulates how a set of objects ({@link PartyMember}) interact.
|
* <p>In this example the mediator encapsulates how a set of objects ({@link PartyMember})
|
||||||
* Instead of referring to each other directly they use the mediator ({@link Party}) interface.
|
* interact. Instead of referring to each other directly they use the mediator ({@link Party})
|
||||||
*
|
* interface.
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point.
|
||||||
*
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.mediator;
|
package com.iluwatar.mediator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Hobbit party member.
|
* Hobbit party member.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class Hobbit extends PartyMemberBase {
|
public class Hobbit extends PartyMemberBase {
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.mediator;
|
package com.iluwatar.mediator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Hunter party member.
|
* Hunter party member.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class Hunter extends PartyMemberBase {
|
public class Hunter extends PartyMemberBase {
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.mediator;
|
package com.iluwatar.mediator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Party interface.
|
* Party interface.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface Party {
|
public interface Party {
|
||||||
|
|
||||||
|
@ -27,9 +27,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Party implementation.
|
* Party implementation.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class PartyImpl implements Party {
|
public class PartyImpl implements Party {
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.mediator;
|
package com.iluwatar.mediator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Interface for party members interacting with {@link Party}.
|
* Interface for party members interacting with {@link Party}.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface PartyMember {
|
public interface PartyMember {
|
||||||
|
|
||||||
|
@ -27,9 +27,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Abstract base class for party members.
|
* Abstract base class for party members.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public abstract class PartyMemberBase implements PartyMember {
|
public abstract class PartyMemberBase implements PartyMember {
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.mediator;
|
package com.iluwatar.mediator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Rogue party member.
|
* Rogue party member.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class Rogue extends PartyMemberBase {
|
public class Rogue extends PartyMemberBase {
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.mediator;
|
package com.iluwatar.mediator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Wizard party member.
|
* Wizard party member.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class Wizard extends PartyMemberBase {
|
public class Wizard extends PartyMemberBase {
|
||||||
|
|
||||||
|
@ -23,36 +23,33 @@
|
|||||||
|
|
||||||
package com.iluwatar.memento;
|
package com.iluwatar.memento;
|
||||||
|
|
||||||
|
import java.util.Stack;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* The Memento pattern is a software design pattern that provides the ability to restore an object
|
* The Memento pattern is a software design pattern that provides the ability to restore an object
|
||||||
* to its previous state (undo via rollback).
|
* to its previous state (undo via rollback).
|
||||||
* <p>
|
*
|
||||||
* The Memento pattern is implemented with three objects: the originator, a caretaker and a memento.
|
* <p>The Memento pattern is implemented with three objects: the originator, a caretaker and a
|
||||||
* The originator is some object that has an internal state. The caretaker is going to do something
|
* memento. The originator is some object that has an internal state. The caretaker is going to do
|
||||||
* to the originator, but wants to be able to undo the change. The caretaker first asks the
|
* something to the originator, but wants to be able to undo the change. The caretaker first asks
|
||||||
* originator for a memento object. Then it does whatever operation (or sequence of operations) it
|
* the originator for a memento object. Then it does whatever operation (or sequence of operations)
|
||||||
* was going to do. To roll back to the state before the operations, it returns the memento object
|
* it was going to do. To roll back to the state before the operations, it returns the memento
|
||||||
* to the originator. The memento object itself is an opaque object (one which the caretaker cannot,
|
* object to the originator. The memento object itself is an opaque object (one which the caretaker
|
||||||
* or should not, change). When using this pattern, care should be taken if the originator may
|
* cannot, or should not, change). When using this pattern, care should be taken if the originator
|
||||||
* change other objects or resources - the memento pattern operates on a single object.
|
* may change other objects or resources - the memento pattern operates on a single object.
|
||||||
* <p>
|
*
|
||||||
* In this example the object ({@link Star}) gives out a "memento" ({@link StarMemento}) that
|
* <p>In this example the object ({@link Star}) gives out a "memento" ({@link StarMemento}) that
|
||||||
* contains the state of the object. Later on the memento can be set back to the object restoring
|
* contains the state of the object. Later on the memento can be set back to the object restoring
|
||||||
* the state.
|
* the state.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point.
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Stack<StarMemento> states = new Stack<>();
|
Stack<StarMemento> states = new Stack<>();
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.memento;
|
package com.iluwatar.memento;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Star uses "mementos" to store and restore state.
|
* Star uses "mementos" to store and restore state.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class Star {
|
public class Star {
|
||||||
|
|
||||||
@ -35,7 +33,7 @@ public class Star {
|
|||||||
private int massTons;
|
private int massTons;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public Star(StarType startType, int startAge, int startMass) {
|
public Star(StarType startType, int startAge, int startMass) {
|
||||||
this.type = startType;
|
this.type = startType;
|
||||||
@ -44,7 +42,7 @@ public class Star {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes time pass for the star
|
* Makes time pass for the star.
|
||||||
*/
|
*/
|
||||||
public void timePasses() {
|
public void timePasses() {
|
||||||
ageYears *= 2;
|
ageYears *= 2;
|
||||||
@ -96,9 +94,7 @@ public class Star {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* StarMemento implementation.
|
||||||
* StarMemento implementation
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private static class StarMementoInternal implements StarMemento {
|
private static class StarMementoInternal implements StarMemento {
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.memento;
|
package com.iluwatar.memento;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* External interface to memento.
|
* External interface to memento.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface StarMemento {
|
public interface StarMemento {
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.memento;
|
package com.iluwatar.memento;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* StarType enumeration.
|
||||||
* StarType enumeration
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public enum StarType {
|
public enum StarType {
|
||||||
|
|
||||||
|
@ -24,27 +24,25 @@
|
|||||||
package com.iluwatar.model.view.controller;
|
package com.iluwatar.model.view.controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Model-View-Controller is a pattern for implementing user interfaces. It divides the application
|
* Model-View-Controller is a pattern for implementing user interfaces. It divides the application
|
||||||
* into three interconnected parts namely the model, the view and the controller.
|
* into three interconnected parts namely the model, the view and the controller.
|
||||||
* <p>
|
|
||||||
* The central component of MVC, the model, captures the behavior of the application in terms of its
|
|
||||||
* problem domain, independent of the user interface. The model directly manages the data, logic and
|
|
||||||
* rules of the application. A view can be any output representation of information, such as a chart
|
|
||||||
* or a diagram The third part, the controller, accepts input and converts it to commands for the
|
|
||||||
* model or view.
|
|
||||||
* <p>
|
|
||||||
* In this example we have a giant ({@link GiantModel}) with statuses for health, fatigue and
|
|
||||||
* nourishment. {@link GiantView} can display the giant with its current status.
|
|
||||||
* {@link GiantController} receives input affecting the model and delegates redrawing the giant to
|
|
||||||
* the view.
|
|
||||||
*
|
*
|
||||||
|
* <p>The central component of MVC, the model, captures the behavior of the application in terms of
|
||||||
|
* its problem domain, independent of the user interface. The model directly manages the data, logic
|
||||||
|
* and rules of the application. A view can be any output representation of information, such as a
|
||||||
|
* chart or a diagram The third part, the controller, accepts input and converts it to commands for
|
||||||
|
* the model or view.
|
||||||
|
*
|
||||||
|
* <p>In this example we have a giant ({@link GiantModel}) with statuses for health, fatigue and
|
||||||
|
* nourishment. {@link GiantView} can display the giant with its current status. {@link
|
||||||
|
* GiantController} receives input affecting the model and delegates redrawing the giant to the
|
||||||
|
* view.
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point.
|
||||||
*
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.model.view.controller;
|
package com.iluwatar.model.view.controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Fatigue enumeration.
|
||||||
* Fatigue enumeration
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public enum Fatigue {
|
public enum Fatigue {
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.model.view.controller;
|
package com.iluwatar.model.view.controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* GiantController can update the giant data and redraw it using the view.
|
* GiantController can update the giant data and redraw it using the view.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class GiantController {
|
public class GiantController {
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.model.view.controller;
|
package com.iluwatar.model.view.controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* GiantModel contains the giant data.
|
||||||
* GiantModel contains the giant data
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class GiantModel {
|
public class GiantModel {
|
||||||
|
|
||||||
|
@ -27,9 +27,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* GiantView displays the giant.
|
||||||
* GiantView displays the giant
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class GiantView {
|
public class GiantView {
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.model.view.controller;
|
package com.iluwatar.model.view.controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Health enumeration.
|
||||||
* Health enumeration
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public enum Health {
|
public enum Health {
|
||||||
|
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.model.view.controller;
|
package com.iluwatar.model.view.controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Nourishment enumeration.
|
||||||
* Nourishment enumeration
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public enum Nourishment {
|
public enum Nourishment {
|
||||||
|
|
||||||
|
@ -24,31 +24,29 @@
|
|||||||
package com.iluwatar.model.view.presenter;
|
package com.iluwatar.model.view.presenter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* The Model-View-Presenter(MVP) architectural pattern, helps us achieve what is called "The
|
||||||
* The Model-View-Presenter(MVP) architectural pattern, helps us achieve what is called
|
* separation of concerns" principle. This is accomplished by separating the application's logic
|
||||||
* "The separation of concerns" principle. This is accomplished by separating the application's
|
* (Model), GUIs (View), and finally the way that the user's actions update the application's logic
|
||||||
* logic (Model), GUIs (View), and finally the way that the user's actions update the application's
|
* (Presenter).
|
||||||
* logic (Presenter).
|
*
|
||||||
* <p>
|
* <p>In the following example, The {@link FileLoader} class represents the app's logic, the {@link
|
||||||
* In the following example, The {@link FileLoader} class represents the app's logic, the
|
* FileSelectorJFrame} is the GUI and the {@link FileSelectorPresenter} is responsible to respond to
|
||||||
* {@link FileSelectorJFrame} is the GUI and the {@link FileSelectorPresenter} is responsible to
|
* users' actions.
|
||||||
* respond to users' actions.
|
*
|
||||||
* <p>
|
* <p>Finally, please notice the wiring between the Presenter and the View and between the
|
||||||
* Finally, please notice the wiring between the Presenter and the View and between the Presenter
|
* Presenter and the Model.
|
||||||
* and the Model.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point.
|
||||||
*
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
FileLoader loader = new FileLoader();
|
FileLoader loader = new FileLoader();
|
||||||
FileSelectorJFrame jFrame = new FileSelectorJFrame();
|
FileSelectorJFrame frame = new FileSelectorJFrame();
|
||||||
FileSelectorPresenter presenter = new FileSelectorPresenter(jFrame);
|
FileSelectorPresenter presenter = new FileSelectorPresenter(frame);
|
||||||
presenter.setLoader(loader);
|
presenter.setLoader(loader);
|
||||||
presenter.start();
|
presenter.start();
|
||||||
}
|
}
|
||||||
|
@ -27,23 +27,22 @@ import java.io.BufferedReader;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every instance of this class represents the Model component in the Model-View-Presenter
|
* Every instance of this class represents the Model component in the Model-View-Presenter
|
||||||
* architectural pattern.
|
* architectural pattern.
|
||||||
* <p>
|
*
|
||||||
* It is responsible for reading and loading the contents of a given file.
|
* <p>It is responsible for reading and loading the contents of a given file.
|
||||||
*/
|
*/
|
||||||
public class FileLoader implements Serializable {
|
public class FileLoader implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generated serial version UID
|
* Generated serial version UID.
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = -4745803872902019069L;
|
private static final long serialVersionUID = -4745803872902019069L;
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(FileLoader.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(FileLoader.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,7 +80,7 @@ public class FileLoader implements Serializable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the path of the file to be loaded, to the given value.
|
* Sets the path of the file to be loaded, to the given value.
|
||||||
*
|
*
|
||||||
* @param fileName The path of the file to be loaded.
|
* @param fileName The path of the file to be loaded.
|
||||||
*/
|
*/
|
||||||
public void setFileName(String fileName) {
|
public void setFileName(String fileName) {
|
||||||
@ -89,6 +88,8 @@ public class FileLoader implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the path of the file to be loaded.
|
||||||
|
*
|
||||||
* @return fileName The path of the file to be loaded.
|
* @return fileName The path of the file to be loaded.
|
||||||
*/
|
*/
|
||||||
public String getFileName() {
|
public String getFileName() {
|
||||||
@ -96,6 +97,8 @@ public class FileLoader implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns true if the given file exists.
|
||||||
|
*
|
||||||
* @return True, if the file given exists, false otherwise.
|
* @return True, if the file given exists, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean fileExists() {
|
public boolean fileExists() {
|
||||||
@ -103,6 +106,8 @@ public class FileLoader implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns true if the given file is loaded.
|
||||||
|
*
|
||||||
* @return True, if the file is loaded, false otherwise.
|
* @return True, if the file is loaded, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isLoaded() {
|
public boolean isLoaded() {
|
||||||
|
@ -26,7 +26,6 @@ package com.iluwatar.model.view.presenter;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
@ -82,7 +81,7 @@ public class FileSelectorJFrame extends JFrame implements FileSelectorView, Acti
|
|||||||
private JPanel panel;
|
private JPanel panel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Presenter component that the frame will interact with
|
* The Presenter component that the frame will interact with.
|
||||||
*/
|
*/
|
||||||
private FileSelectorPresenter presenter;
|
private FileSelectorPresenter presenter;
|
||||||
|
|
||||||
|
@ -28,13 +28,13 @@ import java.io.Serializable;
|
|||||||
/**
|
/**
|
||||||
* Every instance of this class represents the Presenter component in the Model-View-Presenter
|
* Every instance of this class represents the Presenter component in the Model-View-Presenter
|
||||||
* architectural pattern.
|
* architectural pattern.
|
||||||
* <p>
|
*
|
||||||
* It is responsible for reacting to the user's actions and update the View component.
|
* <p>It is responsible for reacting to the user's actions and update the View component.
|
||||||
*/
|
*/
|
||||||
public class FileSelectorPresenter implements Serializable {
|
public class FileSelectorPresenter implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generated serial version UID
|
* Generated serial version UID.
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 1210314339075855074L;
|
private static final long serialVersionUID = 1210314339075855074L;
|
||||||
|
|
||||||
@ -49,8 +49,8 @@ public class FileSelectorPresenter implements Serializable {
|
|||||||
private FileLoader loader;
|
private FileLoader loader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param view The view component that the presenter will interact with.
|
* @param view The view component that the presenter will interact with.
|
||||||
*/
|
*/
|
||||||
public FileSelectorPresenter(FileSelectorView view) {
|
public FileSelectorPresenter(FileSelectorView view) {
|
||||||
@ -59,7 +59,7 @@ public class FileSelectorPresenter implements Serializable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link FileLoader} object, to the value given as parameter.
|
* Sets the {@link FileLoader} object, to the value given as parameter.
|
||||||
*
|
*
|
||||||
* @param loader The new {@link FileLoader} object(the Model component).
|
* @param loader The new {@link FileLoader} object(the Model component).
|
||||||
*/
|
*/
|
||||||
public void setLoader(FileLoader loader) {
|
public void setLoader(FileLoader loader) {
|
||||||
@ -82,7 +82,7 @@ public class FileSelectorPresenter implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ok button handler
|
* Ok button handler.
|
||||||
*/
|
*/
|
||||||
public void confirmed() {
|
public void confirmed() {
|
||||||
if (loader.getFileName() == null || loader.getFileName().equals("")) {
|
if (loader.getFileName() == null || loader.getFileName().equals("")) {
|
||||||
|
@ -26,12 +26,12 @@ package com.iluwatar.model.view.presenter;
|
|||||||
/**
|
/**
|
||||||
* Every instance of this class represents the Stub component in the Model-View-Presenter
|
* Every instance of this class represents the Stub component in the Model-View-Presenter
|
||||||
* architectural pattern.
|
* architectural pattern.
|
||||||
* <p>
|
*
|
||||||
* The stub implements the View interface and it is useful when we want the test the reaction to
|
* <p>The stub implements the View interface and it is useful when we want the test the reaction to
|
||||||
* user events, such as mouse clicks.
|
* user events, such as mouse clicks.
|
||||||
* <p>
|
*
|
||||||
* Since we can not test the GUI directly, the MVP pattern provides this functionality through the
|
* <p>Since we can not test the GUI directly, the MVP pattern provides this functionality through
|
||||||
* View's dummy implementation, the Stub.
|
* the View's dummy implementation, the Stub.
|
||||||
*/
|
*/
|
||||||
public class FileSelectorStub implements FileSelectorView {
|
public class FileSelectorStub implements FileSelectorView {
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ public class FileSelectorStub implements FileSelectorView {
|
|||||||
private boolean dataDisplayed;
|
private boolean dataDisplayed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public FileSelectorStub() {
|
public FileSelectorStub() {
|
||||||
this.opened = false;
|
this.opened = false;
|
||||||
@ -124,6 +124,8 @@ public class FileSelectorStub implements FileSelectorView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns true, if the data were displayed.
|
||||||
|
*
|
||||||
* @return True if the data where displayed, false otherwise.
|
* @return True if the data where displayed, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean dataDisplayed() {
|
public boolean dataDisplayed() {
|
||||||
|
@ -42,44 +42,50 @@ public interface FileSelectorView extends Serializable {
|
|||||||
void close();
|
void close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns true if view is opened.
|
||||||
|
*
|
||||||
* @return True, if the view is opened, false otherwise.
|
* @return True, if the view is opened, false otherwise.
|
||||||
*/
|
*/
|
||||||
boolean isOpened();
|
boolean isOpened();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the presenter component, to the one given as parameter.
|
* Sets the presenter component, to the one given as parameter.
|
||||||
*
|
*
|
||||||
* @param presenter The new presenter component.
|
* @param presenter The new presenter component.
|
||||||
*/
|
*/
|
||||||
void setPresenter(FileSelectorPresenter presenter);
|
void setPresenter(FileSelectorPresenter presenter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets presenter component.
|
||||||
|
*
|
||||||
* @return The presenter Component.
|
* @return The presenter Component.
|
||||||
*/
|
*/
|
||||||
FileSelectorPresenter getPresenter();
|
FileSelectorPresenter getPresenter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the file's name, to the value given as parameter.
|
* Sets the file's name, to the value given as parameter.
|
||||||
*
|
*
|
||||||
* @param name The new name of the file.
|
* @param name The new name of the file.
|
||||||
*/
|
*/
|
||||||
void setFileName(String name);
|
void setFileName(String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the name of file.
|
||||||
|
*
|
||||||
* @return The name of the file.
|
* @return The name of the file.
|
||||||
*/
|
*/
|
||||||
String getFileName();
|
String getFileName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a message to the users.
|
* Displays a message to the users.
|
||||||
*
|
*
|
||||||
* @param message The message to be displayed.
|
* @param message The message to be displayed.
|
||||||
*/
|
*/
|
||||||
void showMessage(String message);
|
void showMessage(String message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays the data to the view.
|
* Displays the data to the view.
|
||||||
*
|
*
|
||||||
* @param data The data to be written.
|
* @param data The data to be written.
|
||||||
*/
|
*/
|
||||||
void displayData(String data);
|
void displayData(String data);
|
||||||
|
@ -31,10 +31,9 @@ import java.io.FileNotFoundException;
|
|||||||
* An object that applies this pattern can provide the equivalent of a namespace, providing the
|
* An object that applies this pattern can provide the equivalent of a namespace, providing the
|
||||||
* initialization and finalization process of a static class or a class with static members with
|
* initialization and finalization process of a static class or a class with static members with
|
||||||
* cleaner, more concise syntax and semantics.
|
* cleaner, more concise syntax and semantics.
|
||||||
* <p>
|
*
|
||||||
* The below example demonstrates a use case for testing two different modules: File Logger and
|
* <p>The below example demonstrates a use case for testing two different modules: File Logger and
|
||||||
* Console Logger
|
* Console Logger
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
@ -42,10 +41,10 @@ public class App {
|
|||||||
public static ConsoleLoggerModule consoleLoggerModule;
|
public static ConsoleLoggerModule consoleLoggerModule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Following method performs the initialization
|
* Following method performs the initialization.
|
||||||
*
|
*
|
||||||
* @throws FileNotFoundException if program is not able to find log files (output.txt and
|
* @throws FileNotFoundException if program is not able to find log files (output.txt and
|
||||||
* error.txt)
|
* error.txt)
|
||||||
*/
|
*/
|
||||||
public static void prepare() throws FileNotFoundException {
|
public static void prepare() throws FileNotFoundException {
|
||||||
|
|
||||||
@ -55,7 +54,7 @@ public class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Following method performs the finalization
|
* Following method performs the finalization.
|
||||||
*/
|
*/
|
||||||
public static void unprepare() {
|
public static void unprepare() {
|
||||||
|
|
||||||
@ -65,8 +64,8 @@ public class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Following method is main executor
|
* Following method is main executor.
|
||||||
*
|
*
|
||||||
* @param args for providing default program arguments
|
* @param args for providing default program arguments
|
||||||
*/
|
*/
|
||||||
public static void execute(final String... args) {
|
public static void execute(final String... args) {
|
||||||
@ -82,10 +81,10 @@ public class App {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
*
|
*
|
||||||
* @param args command line args.
|
* @param args command line args.
|
||||||
* @throws FileNotFoundException if program is not able to find log files (output.txt and
|
* @throws FileNotFoundException if program is not able to find log files (output.txt and
|
||||||
* error.txt)
|
* error.txt)
|
||||||
*/
|
*/
|
||||||
public static void main(final String... args) throws FileNotFoundException {
|
public static void main(final String... args) throws FileNotFoundException {
|
||||||
prepare();
|
prepare();
|
||||||
|
@ -23,16 +23,15 @@
|
|||||||
|
|
||||||
package com.iluwatar.module;
|
package com.iluwatar.module;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ConsoleLoggerModule is responsible for showing logs on System Console
|
* The ConsoleLoggerModule is responsible for showing logs on System Console.
|
||||||
* <p>
|
*
|
||||||
* The below example demonstrates a Console logger module, which can print simple and error messages
|
* <p>The below example demonstrates a Console logger module, which can print simple and error
|
||||||
* in two designated formats
|
* messages in two designated formats
|
||||||
*/
|
*/
|
||||||
public final class ConsoleLoggerModule {
|
public final class ConsoleLoggerModule {
|
||||||
|
|
||||||
@ -43,11 +42,12 @@ public final class ConsoleLoggerModule {
|
|||||||
public PrintStream output = null;
|
public PrintStream output = null;
|
||||||
public PrintStream error = null;
|
public PrintStream error = null;
|
||||||
|
|
||||||
private ConsoleLoggerModule() {}
|
private ConsoleLoggerModule() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static method to get single instance of class
|
* Static method to get single instance of class.
|
||||||
*
|
*
|
||||||
* @return singleton instance of ConsoleLoggerModule
|
* @return singleton instance of ConsoleLoggerModule
|
||||||
*/
|
*/
|
||||||
public static ConsoleLoggerModule getSingleton() {
|
public static ConsoleLoggerModule getSingleton() {
|
||||||
@ -60,7 +60,7 @@ public final class ConsoleLoggerModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Following method performs the initialization
|
* Following method performs the initialization.
|
||||||
*/
|
*/
|
||||||
public ConsoleLoggerModule prepare() {
|
public ConsoleLoggerModule prepare() {
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ public final class ConsoleLoggerModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Following method performs the finalization
|
* Following method performs the finalization.
|
||||||
*/
|
*/
|
||||||
public void unprepare() {
|
public void unprepare() {
|
||||||
|
|
||||||
@ -93,8 +93,8 @@ public final class ConsoleLoggerModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to print a message
|
* Used to print a message.
|
||||||
*
|
*
|
||||||
* @param value will be printed on console
|
* @param value will be printed on console
|
||||||
*/
|
*/
|
||||||
public void printString(final String value) {
|
public void printString(final String value) {
|
||||||
@ -102,8 +102,8 @@ public final class ConsoleLoggerModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to print a error message
|
* Used to print a error message.
|
||||||
*
|
*
|
||||||
* @param value will be printed on error console
|
* @param value will be printed on error console
|
||||||
*/
|
*/
|
||||||
public void printErrorString(final String value) {
|
public void printErrorString(final String value) {
|
||||||
|
@ -23,18 +23,17 @@
|
|||||||
|
|
||||||
package com.iluwatar.module;
|
package com.iluwatar.module;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The FileLoggerModule is responsible for showing logs on File System
|
* The FileLoggerModule is responsible for showing logs on File System.
|
||||||
* <p>
|
*
|
||||||
* The below example demonstrates a File logger module, which can print simple and error messages in
|
* <p>The below example demonstrates a File logger module, which can print simple and error
|
||||||
* two designated files
|
* messages in two designated files
|
||||||
*/
|
*/
|
||||||
public final class FileLoggerModule {
|
public final class FileLoggerModule {
|
||||||
|
|
||||||
@ -48,11 +47,12 @@ public final class FileLoggerModule {
|
|||||||
public PrintStream output = null;
|
public PrintStream output = null;
|
||||||
public PrintStream error = null;
|
public PrintStream error = null;
|
||||||
|
|
||||||
private FileLoggerModule() {}
|
private FileLoggerModule() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static method to get single instance of class
|
* Static method to get single instance of class.
|
||||||
*
|
*
|
||||||
* @return singleton instance of FileLoggerModule
|
* @return singleton instance of FileLoggerModule
|
||||||
*/
|
*/
|
||||||
public static FileLoggerModule getSingleton() {
|
public static FileLoggerModule getSingleton() {
|
||||||
@ -65,10 +65,10 @@ public final class FileLoggerModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Following method performs the initialization
|
* Following method performs the initialization.
|
||||||
*
|
*
|
||||||
* @throws FileNotFoundException if program is not able to find log files (output.txt and
|
* @throws FileNotFoundException if program is not able to find log files (output.txt and
|
||||||
* error.txt)
|
* error.txt)
|
||||||
*/
|
*/
|
||||||
public FileLoggerModule prepare() throws FileNotFoundException {
|
public FileLoggerModule prepare() throws FileNotFoundException {
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ public final class FileLoggerModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Following method performs the finalization
|
* Following method performs the finalization.
|
||||||
*/
|
*/
|
||||||
public void unprepare() {
|
public void unprepare() {
|
||||||
|
|
||||||
@ -101,8 +101,8 @@ public final class FileLoggerModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to print a message
|
* Used to print a message.
|
||||||
*
|
*
|
||||||
* @param value will be printed in file
|
* @param value will be printed in file
|
||||||
*/
|
*/
|
||||||
public void printString(final String value) {
|
public void printString(final String value) {
|
||||||
@ -110,8 +110,8 @@ public final class FileLoggerModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to print a error message
|
* Used to print a error message.
|
||||||
*
|
*
|
||||||
* @param value will be printed on error file
|
* @param value will be printed on error file
|
||||||
*/
|
*/
|
||||||
public void printErrorString(final String value) {
|
public void printErrorString(final String value) {
|
||||||
|
@ -23,26 +23,27 @@
|
|||||||
|
|
||||||
package com.iluwatar.monad;
|
package com.iluwatar.monad;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Monad pattern defines a monad structure, that enables chaining operations
|
* The Monad pattern defines a monad structure, that enables chaining operations in pipelines and
|
||||||
* in pipelines and processing data step by step.
|
* processing data step by step. Formally, monad consists of a type constructor M and two
|
||||||
* Formally, monad consists of a type constructor M and two operations:
|
* operations:
|
||||||
* <br>bind - that takes monadic object and a function from plain object to the
|
* <br>bind - that takes monadic object and a function from plain object to the
|
||||||
* monadic value and returns monadic value.
|
* monadic value and returns monadic value.
|
||||||
* <br>return - that takes plain type object and returns this object wrapped in a monadic value.
|
* <br>return - that takes plain type object and returns this object wrapped in a monadic value.
|
||||||
* <p>
|
*
|
||||||
* In the given example, the Monad pattern is represented as a {@link Validator} that takes an instance
|
* <p>In the given example, the Monad pattern is represented as a {@link Validator} that takes an
|
||||||
* of a plain object with {@link Validator#of(Object)}
|
* instance of a plain object with {@link Validator#of(Object)} and validates it {@link
|
||||||
* and validates it {@link Validator#validate(Function, Predicate, String)} against given predicates.
|
* Validator#validate(Function, Predicate, String)} against given predicates.
|
||||||
* <p>As a validation result {@link Validator#get()} it either returns valid object {@link Validator#t}
|
*
|
||||||
* or throws a list of exceptions {@link Validator#exceptions} collected during validation.
|
* <p>As a validation result {@link Validator#get()} it either returns valid object {@link
|
||||||
|
* Validator#t} or throws a list of exceptions {@link Validator#exceptions} collected during
|
||||||
|
* validation.
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
@ -58,6 +59,7 @@ public class App {
|
|||||||
LOGGER.info(Validator.of(user).validate(User::getName, Objects::nonNull, "name is null")
|
LOGGER.info(Validator.of(user).validate(User::getName, Objects::nonNull, "name is null")
|
||||||
.validate(User::getName, name -> !name.isEmpty(), "name is empty")
|
.validate(User::getName, name -> !name.isEmpty(), "name is empty")
|
||||||
.validate(User::getEmail, email -> !email.contains("@"), "email doesn't containt '@'")
|
.validate(User::getEmail, email -> !email.contains("@"), "email doesn't containt '@'")
|
||||||
.validate(User::getAge, age -> age > 20 && age < 30, "age isn't between...").get().toString());
|
.validate(User::getAge, age -> age > 20 && age < 30, "age isn't between...").get()
|
||||||
|
.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
package com.iluwatar.monad;
|
package com.iluwatar.monad;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumeration of Types of Sex
|
* Enumeration of Types of Sex.
|
||||||
*/
|
*/
|
||||||
public enum Sex {
|
public enum Sex {
|
||||||
MALE, FEMALE
|
MALE, FEMALE
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
package com.iluwatar.monad;
|
package com.iluwatar.monad;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User Definition
|
* User Definition.
|
||||||
*/
|
*/
|
||||||
public class User {
|
public class User {
|
||||||
|
|
||||||
@ -34,6 +34,8 @@ public class User {
|
|||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
* @param name - name
|
* @param name - name
|
||||||
* @param age - age
|
* @param age - age
|
||||||
* @param sex - sex
|
* @param sex - sex
|
||||||
|
@ -30,18 +30,18 @@ import java.util.function.Function;
|
|||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing Monad design pattern. Monad is a way of chaining operations on the
|
* Class representing Monad design pattern. Monad is a way of chaining operations on the given
|
||||||
* given object together step by step. In Validator each step results in either success or
|
* object together step by step. In Validator each step results in either success or failure
|
||||||
* failure indicator, giving a way of receiving each of them easily and finally getting
|
* indicator, giving a way of receiving each of them easily and finally getting validated object or
|
||||||
* validated object or list of exceptions.
|
* list of exceptions.
|
||||||
*
|
*
|
||||||
* @param <T> Placeholder for an object.
|
* @param <T> Placeholder for an object.
|
||||||
*/
|
*/
|
||||||
public class Validator<T> {
|
public class Validator<T> {
|
||||||
/**
|
/**
|
||||||
* Object that is validated
|
* Object that is validated.
|
||||||
*/
|
*/
|
||||||
private final T t;
|
private final T obj;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of exception thrown during validation.
|
* List of exception thrown during validation.
|
||||||
@ -50,14 +50,15 @@ public class Validator<T> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a monadic value of given object.
|
* Creates a monadic value of given object.
|
||||||
* @param t object to be validated
|
*
|
||||||
|
* @param obj object to be validated
|
||||||
*/
|
*/
|
||||||
private Validator(T t) {
|
private Validator(T obj) {
|
||||||
this.t = t;
|
this.obj = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates validator against given object
|
* Creates validator against given object.
|
||||||
*
|
*
|
||||||
* @param t object to be validated
|
* @param t object to be validated
|
||||||
* @param <T> object's type
|
* @param <T> object's type
|
||||||
@ -68,25 +69,27 @@ public class Validator<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param validation one argument boolean-valued function that
|
* Checks if the validation is successful.
|
||||||
* represents one step of validation. Adds exception to main validation exception
|
*
|
||||||
* list when single step validation ends with failure.
|
* @param validation one argument boolean-valued function that represents one step of validation.
|
||||||
|
* Adds exception to main validation exception list when single step validation
|
||||||
|
* ends with failure.
|
||||||
* @param message error message when object is invalid
|
* @param message error message when object is invalid
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public Validator<T> validate(Predicate<T> validation, String message) {
|
public Validator<T> validate(Predicate<T> validation, String message) {
|
||||||
if (!validation.test(t)) {
|
if (!validation.test(obj)) {
|
||||||
exceptions.add(new IllegalStateException(message));
|
exceptions.add(new IllegalStateException(message));
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension for the {@link Validator#validate(Function, Predicate, String)} method,
|
* Extension for the {@link Validator#validate(Function, Predicate, String)} method, dedicated for
|
||||||
* dedicated for objects, that need to be projected before requested validation.
|
* objects, that need to be projected before requested validation.
|
||||||
*
|
*
|
||||||
* @param projection function that gets an objects, and returns projection representing
|
* @param projection function that gets an objects, and returns projection representing element to
|
||||||
* element to be validated.
|
* be validated.
|
||||||
* @param validation see {@link Validator#validate(Function, Predicate, String)}
|
* @param validation see {@link Validator#validate(Function, Predicate, String)}
|
||||||
* @param message see {@link Validator#validate(Function, Predicate, String)}
|
* @param message see {@link Validator#validate(Function, Predicate, String)}
|
||||||
* @param <U> see {@link Validator#validate(Function, Predicate, String)}
|
* @param <U> see {@link Validator#validate(Function, Predicate, String)}
|
||||||
@ -105,7 +108,7 @@ public class Validator<T> {
|
|||||||
*/
|
*/
|
||||||
public T get() throws IllegalStateException {
|
public T get() throws IllegalStateException {
|
||||||
if (exceptions.isEmpty()) {
|
if (exceptions.isEmpty()) {
|
||||||
return t;
|
return obj;
|
||||||
}
|
}
|
||||||
IllegalStateException e = new IllegalStateException();
|
IllegalStateException e = new IllegalStateException();
|
||||||
exceptions.forEach(e::addSuppressed);
|
exceptions.forEach(e::addSuppressed);
|
||||||
|
@ -24,28 +24,22 @@
|
|||||||
package com.iluwatar.monostate;
|
package com.iluwatar.monostate;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* The MonoState pattern ensures that all instances of the class will have the same state. This can
|
* The MonoState pattern ensures that all instances of the class will have the same state. This can
|
||||||
* be used a direct replacement of the Singleton pattern.
|
* be used a direct replacement of the Singleton pattern.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>In the following example, The {@link LoadBalancer} class represents the app's logic. It
|
||||||
* In the following example, The {@link LoadBalancer} class represents the app's logic. It contains
|
* contains a series of Servers, which can handle requests of type {@link Request}. Two instances of
|
||||||
* a series of Servers, which can handle requests of type {@link Request}. Two instances of
|
|
||||||
* LoadBalacer are created. When a request is made to a server via the first LoadBalancer the state
|
* LoadBalacer are created. When a request is made to a server via the first LoadBalancer the state
|
||||||
* change in the first load balancer affects the second. So if the first LoadBalancer selects the
|
* change in the first load balancer affects the second. So if the first LoadBalancer selects the
|
||||||
* Server 1, the second LoadBalancer on a new request will select the Second server. If a third
|
* Server 1, the second LoadBalancer on a new request will select the Second server. If a third
|
||||||
* LoadBalancer is created and a new request is made to it, then it will select the third server as
|
* LoadBalancer is created and a new request is made to it, then it will select the third server as
|
||||||
* the second load balancer has already selected the second server.
|
* the second load balancer has already selected the second server.
|
||||||
* <p>
|
|
||||||
* .
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point.
|
||||||
*
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -31,7 +31,6 @@ import java.util.List;
|
|||||||
* receiving a new Request, it delegates the call to the servers in a Round Robin Fashion. Since all
|
* receiving a new Request, it delegates the call to the servers in a Round Robin Fashion. Since all
|
||||||
* instances of the class share the same state, all instances will delegate to the same server on
|
* instances of the class share the same state, all instances will delegate to the same server on
|
||||||
* receiving a new Request.
|
* receiving a new Request.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class LoadBalancer {
|
public class LoadBalancer {
|
||||||
@ -40,13 +39,13 @@ public class LoadBalancer {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
int id = 0;
|
int id = 0;
|
||||||
for (int port : new int[] {8080, 8081, 8082, 8083, 8084}) {
|
for (int port : new int[]{8080, 8081, 8082, 8083, 8084}) {
|
||||||
SERVERS.add(new Server("localhost", port, ++id));
|
SERVERS.add(new Server("localhost", port, ++id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add new server
|
* Add new server.
|
||||||
*/
|
*/
|
||||||
public final void addServer(Server server) {
|
public final void addServer(Server server) {
|
||||||
synchronized (SERVERS) {
|
synchronized (SERVERS) {
|
||||||
@ -64,7 +63,7 @@ public class LoadBalancer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle request
|
* Handle request.
|
||||||
*/
|
*/
|
||||||
public synchronized void serverRequest(Request request) {
|
public synchronized void serverRequest(Request request) {
|
||||||
if (lastServedId >= SERVERS.size()) {
|
if (lastServedId >= SERVERS.size()) {
|
||||||
@ -73,5 +72,5 @@ public class LoadBalancer {
|
|||||||
Server server = SERVERS.get(lastServedId++);
|
Server server = SERVERS.get(lastServedId++);
|
||||||
server.serve(request);
|
server.serve(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.monostate;
|
package com.iluwatar.monostate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* The Request class. A {@link Server} can handle an instance of a Request.
|
* The Request class. A {@link Server} can handle an instance of a Request.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Request {
|
public class Request {
|
||||||
|
@ -27,10 +27,8 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* The Server class. Each Server sits behind a LoadBalancer which delegates the call to the servers
|
* The Server class. Each Server sits behind a LoadBalancer which delegates the call to the servers
|
||||||
* in a simplistic Round Robin fashion.
|
* in a simplistic Round Robin fashion.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class Server {
|
public class Server {
|
||||||
|
|
||||||
@ -41,7 +39,7 @@ public class Server {
|
|||||||
public final int id;
|
public final int id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public Server(String host, int port, int id) {
|
public Server(String host, int port, int id) {
|
||||||
this.host = host;
|
this.host = host;
|
||||||
@ -59,6 +57,6 @@ public class Server {
|
|||||||
|
|
||||||
public void serve(Request request) {
|
public void serve(Request request) {
|
||||||
LOGGER.info("Server ID {} associated to host : {} and port {}. Processed request with value {}",
|
LOGGER.info("Server ID {} associated to host : {} and port {}. Processed request with value {}",
|
||||||
id, host, port, request.value);
|
id, host, port, request.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,26 +27,24 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Whereas Singleton design pattern introduces single globally accessible object the Multiton
|
* Whereas Singleton design pattern introduces single globally accessible object the Multiton
|
||||||
* pattern defines many globally accessible objects. The client asks for the correct instance from
|
* pattern defines many globally accessible objects. The client asks for the correct instance from
|
||||||
* the Multiton by passing an enumeration as parameter.
|
* the Multiton by passing an enumeration as parameter.
|
||||||
* <p>
|
|
||||||
* There is more than one way to implement the multiton design pattern. In the first example
|
|
||||||
* {@link Nazgul} is the Multiton and we can ask single {@link Nazgul} from it using {@link NazgulName}.
|
|
||||||
* The {@link Nazgul}s are statically initialized and stored in concurrent hash map.
|
|
||||||
* <p>
|
|
||||||
* In the enum implementation {@link NazgulEnum} is the multiton. It is static and mutable because
|
|
||||||
* of the way java supports enums.
|
|
||||||
*
|
*
|
||||||
|
* <p>There is more than one way to implement the multiton design pattern. In the first example
|
||||||
|
* {@link Nazgul} is the Multiton and we can ask single {@link Nazgul} from it using {@link
|
||||||
|
* NazgulName}. The {@link Nazgul}s are statically initialized and stored in concurrent hash map.
|
||||||
|
*
|
||||||
|
* <p>In the enum implementation {@link NazgulEnum} is the multiton. It is static and mutable
|
||||||
|
* because of the way java supports enums.
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point
|
* Program entry point.
|
||||||
*
|
*
|
||||||
* @param args command line args
|
* @param args command line args
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@ -60,7 +58,7 @@ public class App {
|
|||||||
LOGGER.info("ADUNAPHEL={}", Nazgul.getInstance(NazgulName.ADUNAPHEL));
|
LOGGER.info("ADUNAPHEL={}", Nazgul.getInstance(NazgulName.ADUNAPHEL));
|
||||||
LOGGER.info("REN={}", Nazgul.getInstance(NazgulName.REN));
|
LOGGER.info("REN={}", Nazgul.getInstance(NazgulName.REN));
|
||||||
LOGGER.info("UVATHA={}", Nazgul.getInstance(NazgulName.UVATHA));
|
LOGGER.info("UVATHA={}", Nazgul.getInstance(NazgulName.UVATHA));
|
||||||
|
|
||||||
// enum multiton
|
// enum multiton
|
||||||
LOGGER.info("KHAMUL={}", NazgulEnum.KHAMUL);
|
LOGGER.info("KHAMUL={}", NazgulEnum.KHAMUL);
|
||||||
LOGGER.info("MURAZOR={}", NazgulEnum.MURAZOR);
|
LOGGER.info("MURAZOR={}", NazgulEnum.MURAZOR);
|
||||||
|
@ -27,9 +27,7 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Nazgul is a Multiton class. Nazgul instances can be queried using {@link #getInstance} method.
|
* Nazgul is a Multiton class. Nazgul instances can be queried using {@link #getInstance} method.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public final class Nazgul {
|
public final class Nazgul {
|
||||||
|
|
||||||
|
@ -24,11 +24,10 @@
|
|||||||
package com.iluwatar.multiton;
|
package com.iluwatar.multiton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum based multiton implementation
|
* enum based multiton implementation.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public enum NazgulEnum {
|
public enum NazgulEnum {
|
||||||
|
|
||||||
KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA;
|
KHAMUL, MURAZOR, DWAR, JI_INDUR, AKHORAHIL, HOARMURATH, ADUNAPHEL, REN, UVATHA;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
package com.iluwatar.multiton;
|
package com.iluwatar.multiton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Each Nazgul has different {@link NazgulName}.
|
* Each Nazgul has different {@link NazgulName}.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public enum NazgulName {
|
public enum NazgulName {
|
||||||
|
|
||||||
|
@ -23,19 +23,17 @@
|
|||||||
|
|
||||||
package com.iluwatar.mute;
|
package com.iluwatar.mute;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mute pattern is utilized when we need to suppress an exception due to an API flaw or in
|
* Mute pattern is utilized when we need to suppress an exception due to an API flaw or in situation
|
||||||
* situation when all we can do to handle the exception is to log it.
|
* when all we can do to handle the exception is to log it. This pattern should not be used
|
||||||
* This pattern should not be used everywhere. It is very important to logically handle the
|
* everywhere. It is very important to logically handle the exceptions in a system, but some
|
||||||
* exceptions in a system, but some situations like the ones described above require this pattern,
|
* situations like the ones described above require this pattern, so that we don't need to repeat
|
||||||
* so that we don't need to repeat
|
|
||||||
* <pre>
|
* <pre>
|
||||||
* <code>
|
* <code>
|
||||||
* try {
|
* try {
|
||||||
@ -45,7 +43,6 @@ import java.sql.SQLException;
|
|||||||
* }
|
* }
|
||||||
* </code>
|
* </code>
|
||||||
* </pre> every time we need to ignore an exception.
|
* </pre> every time we need to ignore an exception.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
@ -53,7 +50,7 @@ public class App {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Program entry point.
|
* Program entry point.
|
||||||
*
|
*
|
||||||
* @param args command line args.
|
* @param args command line args.
|
||||||
* @throws Exception if any exception occurs
|
* @throws Exception if any exception occurs
|
||||||
*/
|
*/
|
||||||
@ -65,7 +62,7 @@ public class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Typically used when the API declares some exception but cannot do so. Usually a
|
* Typically used when the API declares some exception but cannot do so. Usually a
|
||||||
* signature mistake.In this example out is not supposed to throw exception as it is a
|
* signature mistake.In this example out is not supposed to throw exception as it is a
|
||||||
* ByteArrayOutputStream. So we utilize mute, which will throw AssertionError if unexpected
|
* ByteArrayOutputStream. So we utilize mute, which will throw AssertionError if unexpected
|
||||||
* exception occurs.
|
* exception occurs.
|
||||||
@ -98,7 +95,7 @@ public class App {
|
|||||||
|
|
||||||
private static Resource acquireResource() throws SQLException {
|
private static Resource acquireResource() throws SQLException {
|
||||||
return new Resource() {
|
return new Resource() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
throw new IOException("Error in closing resource: " + this);
|
throw new IOException("Error in closing resource: " + this);
|
||||||
|
@ -25,12 +25,12 @@ package com.iluwatar.mute;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A runnable which may throw exception on execution.
|
* A runnable which may throw exception on execution.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface CheckedRunnable {
|
public interface CheckedRunnable {
|
||||||
/**
|
/**
|
||||||
* Same as {@link Runnable#run()} with a possibility of exception in execution.
|
* Same as {@link Runnable#run()} with a possibility of exception in execution.
|
||||||
|
*
|
||||||
* @throws Exception if any exception occurs.
|
* @throws Exception if any exception occurs.
|
||||||
*/
|
*/
|
||||||
void run() throws Exception;
|
void run() throws Exception;
|
||||||
|
@ -30,17 +30,18 @@ import java.io.IOException;
|
|||||||
* A utility class that allows you to utilize mute idiom.
|
* A utility class that allows you to utilize mute idiom.
|
||||||
*/
|
*/
|
||||||
public final class Mute {
|
public final class Mute {
|
||||||
|
|
||||||
// The constructor is never meant to be called.
|
// The constructor is never meant to be called.
|
||||||
private Mute() {}
|
private Mute() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the <code>runnable</code> and throws the exception occurred within a {@link AssertionError}.
|
* Executes the <code>runnable</code> and throws the exception occurred within a {@link
|
||||||
* This method should be utilized to mute the operations that are guaranteed not to throw an exception.
|
* AssertionError}. This method should be utilized to mute the operations that are guaranteed not
|
||||||
* For instance {@link ByteArrayOutputStream#write(byte[])} declares in it's signature that it can throw
|
* to throw an exception. For instance {@link ByteArrayOutputStream#write(byte[])} declares in
|
||||||
* an {@link IOException}, but in reality it cannot. This is because the bulk write method is not overridden
|
* it's signature that it can throw an {@link IOException}, but in reality it cannot. This is
|
||||||
* in {@link ByteArrayOutputStream}.
|
* because the bulk write method is not overridden in {@link ByteArrayOutputStream}.
|
||||||
*
|
*
|
||||||
* @param runnable a runnable that should never throw an exception on execution.
|
* @param runnable a runnable that should never throw an exception on execution.
|
||||||
*/
|
*/
|
||||||
public static void mute(CheckedRunnable runnable) {
|
public static void mute(CheckedRunnable runnable) {
|
||||||
@ -52,11 +53,11 @@ public final class Mute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the <code>runnable</code> and logs the exception occurred on {@link System#err}.
|
* Executes the <code>runnable</code> and logs the exception occurred on {@link System#err}. This
|
||||||
* This method should be utilized to mute the operations about which most you can do is log.
|
* method should be utilized to mute the operations about which most you can do is log. For
|
||||||
* For instance while closing a connection to database, or cleaning up a resource,
|
* instance while closing a connection to database, or cleaning up a resource, all you can do is
|
||||||
* all you can do is log the exception occurred.
|
* log the exception occurred.
|
||||||
*
|
*
|
||||||
* @param runnable a runnable that may throw an exception on execution.
|
* @param runnable a runnable that may throw an exception on execution.
|
||||||
*/
|
*/
|
||||||
public static void loggedMute(CheckedRunnable runnable) {
|
public static void loggedMute(CheckedRunnable runnable) {
|
||||||
|
@ -26,9 +26,8 @@ package com.iluwatar.mute;
|
|||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents any resource that the application might acquire and that must be closed
|
* Represents any resource that the application might acquire and that must be closed after it is
|
||||||
* after it is utilized. Example of such resources can be a database connection, open
|
* utilized. Example of such resources can be a database connection, open files, sockets.
|
||||||
* files, sockets.
|
|
||||||
*/
|
*/
|
||||||
public interface Resource extends Closeable {
|
public interface Resource extends Closeable {
|
||||||
|
|
||||||
|
@ -25,19 +25,17 @@ package com.iluwatar.mutex;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A Mutex prevents multiple threads from accessing a resource simultaneously.
|
* A Mutex prevents multiple threads from accessing a resource simultaneously.
|
||||||
* <p>
|
*
|
||||||
* In this example we have two thieves who are taking beans from a jar.
|
* <p>In this example we have two thieves who are taking beans from a jar. Only one thief can take
|
||||||
* Only one thief can take a bean at a time. This is ensured by a Mutex lock
|
* a bean at a time. This is ensured by a Mutex lock which must be acquired in order to access the
|
||||||
* which must be acquired in order to access the jar. Each thief attempts to
|
* jar. Each thief attempts to acquire the lock, take a bean and then release the lock. If the lock
|
||||||
* acquire the lock, take a bean and then release the lock. If the lock has
|
* has already been acquired, the thief will be prevented from continuing (blocked) until the lock
|
||||||
* already been acquired, the thief will be prevented from continuing (blocked)
|
* has been released. The thieves stop taking beans once there are no beans left to take.
|
||||||
* until the lock has been released. The thieves stop taking beans once there
|
|
||||||
* are no beans left to take.
|
|
||||||
*/
|
*/
|
||||||
public class App {
|
public class App {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* main method
|
* main method.
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Mutex mutex = new Mutex();
|
Mutex mutex = new Mutex();
|
||||||
|
@ -24,9 +24,8 @@
|
|||||||
package com.iluwatar.mutex;
|
package com.iluwatar.mutex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Jar has a resource of beans which can only be accessed by a single Thief
|
* A Jar has a resource of beans which can only be accessed by a single Thief (thread) at any one
|
||||||
* (thread) at any one time. A Mutex lock is used to prevent more than one Thief
|
* time. A Mutex lock is used to prevent more than one Thief taking a bean simultaneously.
|
||||||
* taking a bean simultaneously.
|
|
||||||
*/
|
*/
|
||||||
public class Jar {
|
public class Jar {
|
||||||
|
|
||||||
|
@ -34,16 +34,15 @@ public class Mutex implements Lock {
|
|||||||
private Object owner;
|
private Object owner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current owner of the Mutex, or null if available
|
* Returns the current owner of the Mutex, or null if available.
|
||||||
*/
|
*/
|
||||||
public Object getOwner() {
|
public Object getOwner() {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called by a thread to acquire the lock. If the lock has already
|
* Method called by a thread to acquire the lock. If the lock has already been acquired this will
|
||||||
* been acquired this will wait until the lock has been released to
|
* wait until the lock has been released to re-attempt the acquire.
|
||||||
* re-attempt the acquire.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void acquire() throws InterruptedException {
|
public synchronized void acquire() throws InterruptedException {
|
||||||
|
@ -27,20 +27,20 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thief is a class which continually tries to acquire a jar and take a bean
|
* Thief is a class which continually tries to acquire a jar and take a bean from it. When the jar
|
||||||
* from it. When the jar is empty the thief stops.
|
* is empty the thief stops.
|
||||||
*/
|
*/
|
||||||
public class Thief extends Thread {
|
public class Thief extends Thread {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Thief.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(Thief.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the thief.
|
* The name of the thief.
|
||||||
*/
|
*/
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The jar
|
* The jar.
|
||||||
*/
|
*/
|
||||||
private final Jar jar;
|
private final Jar jar;
|
||||||
|
|
||||||
@ -50,8 +50,7 @@ public class Thief extends Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In the run method the thief repeatedly tries to take a bean until none
|
* In the run method the thief repeatedly tries to take a bean until none are left.
|
||||||
* are left.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user