Resolves checkstyle errors for delegation dependency-injection dirty-flag double-buffer double-checked-locking double-dispatch (#1068)
* Reduces checkstyle errors in delegation * Reduces checkstyle errors in dependency-injection * Reduces checkstyle errors in dirty-flag * Reduces checkstyle errors in double-buffer * Reduces checkstyle errors in double-checked-locking * Reduces checkstyle errors in double-dispatch
This commit is contained in:
		
				
					committed by
					
						 Ilkka Seppälä
						Ilkka Seppälä
					
				
			
			
				
	
			
			
			
						parent
						
							01e489c77b
						
					
				
				
					commit
					f2c91eb836
				
			| @@ -28,23 +28,25 @@ import com.iluwatar.delegation.simple.printers.EpsonPrinter; | |||||||
| import com.iluwatar.delegation.simple.printers.HpPrinter; | import com.iluwatar.delegation.simple.printers.HpPrinter; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * The delegate pattern provides a mechanism to abstract away the implementation and control of the desired action. |  * The delegate pattern provides a mechanism to abstract away the implementation and control of the | ||||||
|  * The class being called in this case {@link PrinterController} is not responsible for the actual desired action, |  * desired action. The class being called in this case {@link PrinterController} is not responsible | ||||||
|  * but is actually delegated to a helper class either {@link CanonPrinter}, {@link EpsonPrinter} or {@link HpPrinter}. |  * for the actual desired action, but is actually delegated to a helper class either {@link | ||||||
|  * The consumer does not have or require knowledge of the actual class carrying out the action, only the |  * CanonPrinter}, {@link EpsonPrinter} or {@link HpPrinter}. The consumer does not have or require | ||||||
|  * container on which they are calling. |  * knowledge of the actual class carrying out the action, only the container on which they are | ||||||
|  |  * calling. | ||||||
|  * |  * | ||||||
|  * In this example the delegates are {@link EpsonPrinter}, {@link HpPrinter} and {@link CanonPrinter} they all implement |  * <p>In this example the delegates are {@link EpsonPrinter}, {@link HpPrinter} and {@link | ||||||
|  * {@link Printer}. The {@link PrinterController} class also implements {@link Printer}. However neither provide the |  * CanonPrinter} they all implement {@link Printer}. The {@link PrinterController} class also | ||||||
|  * functionality of {@link Printer} by printing to the screen, they actually call upon the instance of {@link Printer} |  * implements {@link Printer}. However neither provide the functionality of {@link Printer} by | ||||||
|  * that they were instantiated with. Therefore delegating the behaviour to another class. |  * printing to the screen, they actually call upon the instance of {@link Printer} that they were | ||||||
|  |  * instantiated with. Therefore delegating the behaviour to another class. | ||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|   private static final String MESSAGE_TO_PRINT = "hello world"; |   private static final String MESSAGE_TO_PRINT = "hello world"; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point. | ||||||
|    * |    * | ||||||
|    * @param args command line args |    * @param args command line args | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -38,7 +38,8 @@ public interface Printer { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Method that takes a String to print to the screen. This will be implemented on both the |    * Method that takes a String to print to the screen. This will be implemented on both the | ||||||
|    * controller and the delegate allowing the controller to call the same method on the delegate class. |    * controller and the delegate allowing the controller to call the same method on the delegate | ||||||
|  |    * class. | ||||||
|    * |    * | ||||||
|    * @param message to be printed to the screen |    * @param message to be printed to the screen | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -24,10 +24,10 @@ | |||||||
| package com.iluwatar.delegation.simple; | package com.iluwatar.delegation.simple; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Delegator Class to delegate the implementation of the Printer. |  * Delegator Class to delegate the implementation of the Printer. This ensures two things: - when | ||||||
|  * This ensures two things: |  * the actual implementation of the Printer class changes the delegation will still be operational - | ||||||
|  *  - when the actual implementation of the Printer class changes the delegation will still be operational |  * the actual benefit is observed when there are more than one implementors and they share a | ||||||
|  *  - the actual benefit is observed when there are more than one implementors and they share a delegation control |  * delegation control | ||||||
|  */ |  */ | ||||||
| public class PrinterController implements Printer { | public class PrinterController implements Printer { | ||||||
|  |  | ||||||
| @@ -38,10 +38,10 @@ public class PrinterController implements Printer { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * This method is implemented from {@link Printer} however instead on providing an |    * This method is implemented from {@link Printer} however instead on providing an implementation, | ||||||
|    * implementation, it instead calls upon the class passed through the constructor. This is the delegate, |    * it instead calls upon the class passed through the constructor. This is the delegate, hence the | ||||||
|    * hence the pattern. Therefore meaning that the caller does not care of the implementing class only the owning |    * pattern. Therefore meaning that the caller does not care of the implementing class only the | ||||||
|    * controller. |    * owning controller. | ||||||
|    * |    * | ||||||
|    * @param message to be printed to the screen |    * @param message to be printed to the screen | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -28,8 +28,8 @@ import org.slf4j.Logger; | |||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Specialised Implementation of {@link Printer} for a Canon Printer, in |  * Specialised Implementation of {@link Printer} for a Canon Printer, in this case the message to be | ||||||
|  * this case the message to be printed is appended to "Canon Printer : " |  * printed is appended to "Canon Printer : ". | ||||||
|  * |  * | ||||||
|  * @see Printer |  * @see Printer | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -28,8 +28,8 @@ import org.slf4j.Logger; | |||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Specialised Implementation of {@link Printer} for a Epson Printer, in |  * Specialised Implementation of {@link Printer} for a Epson Printer, in this case the message to be | ||||||
|  * this case the message to be printed is appended to "Epson Printer : " |  * printed is appended to "Epson Printer : ". | ||||||
|  * |  * | ||||||
|  * @see Printer |  * @see Printer | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -28,8 +28,8 @@ import org.slf4j.Logger; | |||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Specialised Implementation of {@link Printer} for a HP Printer, in |  * Specialised Implementation of {@link Printer} for a HP Printer, in this case the message to be | ||||||
|  * this case the message to be printed is appended to "HP Printer : " |  * printed is appended to "HP Printer : ". | ||||||
|  * |  * | ||||||
|  * @see Printer |  * @see Printer | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -23,30 +23,6 @@ | |||||||
|  |  | ||||||
| package com.iluwatar.dependency.injection; | package com.iluwatar.dependency.injection; | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * The MIT License |  | ||||||
|  * Copyright (c) 2014-2017 Ilkka Seppälä |  | ||||||
|  * <p> |  | ||||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy |  | ||||||
|  * of this software and associated documentation files (the "Software"), to deal |  | ||||||
|  * in the Software without restriction, including without limitation the rights |  | ||||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |  | ||||||
|  * copies of the Software, and to permit persons to whom the Software is |  | ||||||
|  * furnished to do so, subject to the following conditions: |  | ||||||
|  * <p> |  | ||||||
|  * The above copyright notice and this permission notice shall be included in |  | ||||||
|  * all copies or substantial portions of the Software. |  | ||||||
|  * <p> |  | ||||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |  | ||||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |  | ||||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |  | ||||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |  | ||||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |  | ||||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |  | ||||||
|  * THE SOFTWARE. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * AdvancedSorceress implements inversion of control. It depends on abstraction that can be injected |  * AdvancedSorceress implements inversion of control. It depends on abstraction that can be injected | ||||||
|  * through its setter. |  * through its setter. | ||||||
|   | |||||||
| @@ -24,10 +24,8 @@ | |||||||
| package com.iluwatar.dependency.injection; | package com.iluwatar.dependency.injection; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  | ||||||
|  * AdvancedWizard implements inversion of control. It depends on abstraction that can be injected |  * AdvancedWizard implements inversion of control. It depends on abstraction that can be injected | ||||||
|  * through its constructor. |  * through its constructor. | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class AdvancedWizard implements Wizard { | public class AdvancedWizard implements Wizard { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -31,25 +31,26 @@ import com.google.inject.Injector; | |||||||
|  * implements so called inversion of control principle. Inversion of control has two specific rules: |  * implements so called inversion of control principle. Inversion of control has two specific rules: | ||||||
|  * - High-level modules should not depend on low-level modules. Both should depend on abstractions. |  * - High-level modules should not depend on low-level modules. Both should depend on abstractions. | ||||||
|  * - Abstractions should not depend on details. Details should depend on abstractions. |  * - Abstractions should not depend on details. Details should depend on abstractions. | ||||||
|  * <p> |  * | ||||||
|  * In this example we show you three different wizards. The first one ({@link SimpleWizard}) is a |  * <p>In this example we show you three different wizards. The first one ({@link SimpleWizard}) is | ||||||
|  * naive implementation violating the inversion of control principle. It depends directly on a |  * a naive implementation violating the inversion of control principle. It depends directly on a | ||||||
|  * concrete implementation which cannot be changed. |  * concrete implementation which cannot be changed. | ||||||
|  * <p> |  * | ||||||
|  * The second and third wizards({@link AdvancedWizard} and {@link AdvancedSorceress}) are more flexible. |  * <p>The second and third wizards({@link AdvancedWizard} and {@link AdvancedSorceress}) are more | ||||||
|  * They do not depend on any concrete implementation but abstraction. They utilizes Dependency Injection |  * flexible. They do not depend on any concrete implementation but abstraction. They utilizes | ||||||
|  * pattern allowing their {@link Tobacco} dependency to be injected through constructor ({@link AdvancedWizard}) |  * Dependency Injection pattern allowing their {@link Tobacco} dependency to be injected through | ||||||
|  * or setter ({@link AdvancedSorceress}). This way, handling the dependency is no longer the wizard's |  * constructor ({@link AdvancedWizard}) or setter ({@link AdvancedSorceress}). This way, handling | ||||||
|  * responsibility. It is resolved outside the wizard class. |  * the dependency is no longer the wizard's responsibility. It is resolved outside the wizard | ||||||
|  * <p> |  * class. | ||||||
|  * The fourth example takes the pattern a step further. It uses Guice framework for Dependency |  * | ||||||
|  |  * <p>The fourth example takes the pattern a step further. It uses Guice framework for Dependency | ||||||
|  * Injection. {@link TobaccoModule} binds a concrete implementation to abstraction. Injector is then |  * Injection. {@link TobaccoModule} binds a concrete implementation to abstraction. Injector is then | ||||||
|  * used to create {@link GuiceWizard} object with correct dependencies. |  * used to create {@link GuiceWizard} object with correct dependencies. | ||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point. | ||||||
|    * |    * | ||||||
|    * @param args command line args |    * @param args command line args | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -26,10 +26,8 @@ package com.iluwatar.dependency.injection; | |||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  | ||||||
|  * GuiceWizard implements inversion of control. Its dependencies are injected through its |  * GuiceWizard implements inversion of control. Its dependencies are injected through its | ||||||
|  * constructor by Guice framework. |  * constructor by Guice framework. | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class GuiceWizard implements Wizard { | public class GuiceWizard implements Wizard { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,9 +24,7 @@ | |||||||
| package com.iluwatar.dependency.injection; | package com.iluwatar.dependency.injection; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * OldTobyTobacco concrete {@link Tobacco} implementation. | ||||||
|  * OldTobyTobacco concrete {@link Tobacco} implementation |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class OldTobyTobacco extends Tobacco { | public class OldTobyTobacco extends Tobacco { | ||||||
| } | } | ||||||
|   | |||||||
| @@ -24,9 +24,7 @@ | |||||||
| package com.iluwatar.dependency.injection; | package com.iluwatar.dependency.injection; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * RivendellTobacco concrete {@link Tobacco} implementation. | ||||||
|  * RivendellTobacco concrete {@link Tobacco} implementation |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class RivendellTobacco extends Tobacco { | public class RivendellTobacco extends Tobacco { | ||||||
| } | } | ||||||
|   | |||||||
| @@ -24,9 +24,7 @@ | |||||||
| package com.iluwatar.dependency.injection; | package com.iluwatar.dependency.injection; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * SecondBreakfastTobacco concrete {@link Tobacco} implementation. | ||||||
|  * SecondBreakfastTobacco concrete {@link Tobacco} implementation |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class SecondBreakfastTobacco extends Tobacco { | public class SecondBreakfastTobacco extends Tobacco { | ||||||
| } | } | ||||||
|   | |||||||
| @@ -24,10 +24,8 @@ | |||||||
| package com.iluwatar.dependency.injection; | package com.iluwatar.dependency.injection; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  | ||||||
|  * Naive Wizard implementation violating the inversion of control principle. It should depend on |  * Naive Wizard implementation violating the inversion of control principle. It should depend on | ||||||
|  * abstraction instead. |  * abstraction instead. | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class SimpleWizard implements Wizard { | public class SimpleWizard implements Wizard { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,9 +27,7 @@ import org.slf4j.Logger; | |||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * Tobacco abstraction. | ||||||
|  * Tobacco abstraction |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public abstract class Tobacco { | public abstract class Tobacco { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,9 +26,7 @@ package com.iluwatar.dependency.injection; | |||||||
| import com.google.inject.AbstractModule; | import com.google.inject.AbstractModule; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  | ||||||
|  * Guice module for binding certain concrete {@link Tobacco} implementation. |  * Guice module for binding certain concrete {@link Tobacco} implementation. | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class TobaccoModule extends AbstractModule { | public class TobaccoModule extends AbstractModule { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,9 +24,7 @@ | |||||||
| package com.iluwatar.dependency.injection; | package com.iluwatar.dependency.injection; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * Wizard interface. | ||||||
|  * Wizard interface |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public interface Wizard { | public interface Wizard { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,45 +23,49 @@ | |||||||
|  |  | ||||||
| package com.iluwatar.dirtyflag; | package com.iluwatar.dirtyflag; | ||||||
|  |  | ||||||
| import org.slf4j.Logger; |  | ||||||
| import org.slf4j.LoggerFactory; |  | ||||||
|  |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.concurrent.Executors; | import java.util.concurrent.Executors; | ||||||
| import java.util.concurrent.ScheduledExecutorService; | import java.util.concurrent.ScheduledExecutorService; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  |  * This application demonstrates the <b>Dirty Flag</b> pattern. The dirty flag behavioral pattern | ||||||
|  |  * allows you to avoid expensive operations that would just need to be done again anyway. This is a | ||||||
|  |  * simple pattern that really just explains how to add a bool value to your class that you can set | ||||||
|  |  * anytime a property changes. This will let your class know that any results it may have previously | ||||||
|  |  * calculated will need to be calculated again when they’re requested. Once the results are | ||||||
|  |  * re-calculated, then the bool value can be cleared. | ||||||
|  * |  * | ||||||
|  * This application demonstrates the <b>Dirty Flag</b> pattern. The dirty flag behavioral pattern allows you to avoid |  * <p>There are some points that need to be considered before diving into using this pattern:- | ||||||
|  * expensive operations that would just need to be done again anyway. This is a simple pattern that really just explains |  * there are some things you’ll need to consider:- (1) Do you need it? This design pattern works | ||||||
|  * how to add a bool value to your class that you can set anytime a property changes. This will let your class know that |  * well when the results to be calculated are difficult or resource intensive to compute. You want | ||||||
|  * any results it may have previously calculated will need to be calculated again when they’re requested. Once the |  * to save them. You also don’t want to be calculating them several times in a row when only the | ||||||
|  * results are re-calculated, then the bool value can be cleared. |  * last one counts. (2) When do you set the dirty flag? Make sure that you set the dirty flag within | ||||||
|  |  * the class itself whenever an important property changes. This property should affect the result | ||||||
|  |  * of the calculated result and by changing the property, that makes the last result invalid. (3) | ||||||
|  |  * When do you clear the dirty flag? It might seem obvious that the dirty flag should be cleared | ||||||
|  |  * whenever the result is calculated with up-to-date information but there are other times when you | ||||||
|  |  * might want to clear the flag. | ||||||
|  * |  * | ||||||
|  * There are some points that need to be considered before diving into using this pattern:- there are some things you’ll |  * <p>In this example, the {@link DataFetcher} holds the <i>dirty flag</i>. It fetches and | ||||||
|  * need to consider:- (1) Do you need it? This design pattern works well when the results to be calculated are difficult |  * re-fetches from <i>world.txt</i> when needed. {@link World} mainly serves the data to the | ||||||
|  * or resource intensive to compute. You want to save them. You also don’t want to be calculating them several times in |  * front-end. | ||||||
|  * a row when only the last one counts. (2) When do you set the dirty flag? Make sure that you set the dirty flag within |  | ||||||
|  * the class itself whenever an important property changes. This property should affect the result of the calculated |  | ||||||
|  * result and by changing the property, that makes the last result invalid. (3) When do you clear the dirty flag? It |  | ||||||
|  * might seem obvious that the dirty flag should be cleared whenever the result is calculated with up-to-date |  | ||||||
|  * information but there are other times when you might want to clear the flag. |  | ||||||
|  * |  | ||||||
|  * In this example, the {@link DataFetcher} holds the <i>dirty flag</i>. It fetches and re-fetches from <i>world.txt</i> |  | ||||||
|  * when needed. {@link World} mainly serves the data to the front-end. |  | ||||||
|  */ |  */ | ||||||
| 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 execution point |    * Program execution point. | ||||||
|    */ |    */ | ||||||
|   public void run() { |   public void run() { | ||||||
|  |  | ||||||
|     final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); |     final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); | ||||||
|     executorService.scheduleAtFixedRate(new Runnable() { |     executorService.scheduleAtFixedRate(new Runnable() { | ||||||
|       final World world = new World(); |       final World world = new World(); | ||||||
|  |  | ||||||
|       @Override |       @Override | ||||||
|       public void run() { |       public void run() { | ||||||
|         List<String> countries = world.fetch(); |         List<String> countries = world.fetch(); | ||||||
| @@ -74,10 +78,9 @@ public class App { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program entry point |    * Program entry point. | ||||||
|    * |    * | ||||||
|    * @param args |    * @param args command line args | ||||||
|    *          command line args |  | ||||||
|    */ |    */ | ||||||
|   public static void main(String[] args) { |   public static void main(String[] args) { | ||||||
|     App app = new App(); |     App app = new App(); | ||||||
|   | |||||||
| @@ -23,22 +23,19 @@ | |||||||
|  |  | ||||||
| package com.iluwatar.dirtyflag; | package com.iluwatar.dirtyflag; | ||||||
|  |  | ||||||
| import org.slf4j.Logger; |  | ||||||
| import org.slf4j.LoggerFactory; |  | ||||||
|  |  | ||||||
| import javax.xml.crypto.Data; |  | ||||||
| import java.io.BufferedReader; | import java.io.BufferedReader; | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.FileReader; | import java.io.FileReader; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * A mock database manager -- Fetches data from a raw file. |  * A mock database manager -- Fetches data from a raw file. | ||||||
|  * |  * | ||||||
|  * @author swaisuan |  * @author swaisuan | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class DataFetcher { | public class DataFetcher { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,11 +27,9 @@ import java.util.ArrayList; | |||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  | ||||||
|  * A middle-layer app that calls/passes along data from the back-end. |  * A middle-layer app that calls/passes along data from the back-end. | ||||||
|  * |  * | ||||||
|  * @author swaisuan |  * @author swaisuan | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class World { | public class World { | ||||||
|  |  | ||||||
| @@ -44,7 +42,6 @@ public class World { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    *  |  | ||||||
|    * Calls {@link DataFetcher} to fetch data from back-end. |    * Calls {@link DataFetcher} to fetch data from back-end. | ||||||
|    * |    * | ||||||
|    * @return List of strings |    * @return List of strings | ||||||
|   | |||||||
| @@ -23,21 +23,19 @@ | |||||||
|  |  | ||||||
| package com.iluwatar.doublebuffer; | package com.iluwatar.doublebuffer; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
| import org.apache.commons.lang3.tuple.MutablePair; | import org.apache.commons.lang3.tuple.MutablePair; | ||||||
| import org.apache.commons.lang3.tuple.Pair; | import org.apache.commons.lang3.tuple.Pair; | ||||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Double buffering is a term used to describe a device that has two buffers. |  * Double buffering is a term used to describe a device that has two buffers. The usage of multiple | ||||||
|  * The usage of multiple buffers increases the overall throughput of a device |  * buffers increases the overall throughput of a device and helps prevents bottlenecks. This example | ||||||
|  * and helps prevents bottlenecks. This example shows using double buffer pattern |  * shows using double buffer pattern on graphics. It is used to show one image or frame while a | ||||||
|  * on graphics. It is used to show one image or frame while a separate frame |  * separate frame is being buffered to be shown next. This method makes animations and games look | ||||||
|  * is being buffered to be shown next. This method makes animations and games |  * more realistic than the same done in a single buffer mode. | ||||||
|  * look more realistic than the same done in a single buffer mode. |  | ||||||
|  */ |  */ | ||||||
| public class App { | public class App { | ||||||
|  |  | ||||||
| @@ -45,10 +43,11 @@ public class App { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Program main entry point. |    * Program main entry point. | ||||||
|  |    * | ||||||
|    * @param args runtime arguments |    * @param args runtime arguments | ||||||
|    */ |    */ | ||||||
|   public static void main(String[] args) { |   public static void main(String[] args) { | ||||||
|     var scene = new Scene(); |     final var scene = new Scene(); | ||||||
|     List<Pair<Integer, Integer>> drawPixels = new ArrayList<>(); |     List<Pair<Integer, Integer>> drawPixels = new ArrayList<>(); | ||||||
|     Pair<Integer, Integer> pixel1 = new MutablePair<>(1, 1); |     Pair<Integer, Integer> pixel1 = new MutablePair<>(1, 1); | ||||||
|     Pair<Integer, Integer> pixel2 = new MutablePair<>(5, 6); |     Pair<Integer, Integer> pixel2 = new MutablePair<>(5, 6); | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ public interface Buffer { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Clear the pixel in (x, y). |    * Clear the pixel in (x, y). | ||||||
|  |    * | ||||||
|    * @param x X coordinate |    * @param x X coordinate | ||||||
|    * @param y Y coordinate |    * @param y Y coordinate | ||||||
|    */ |    */ | ||||||
| @@ -37,6 +38,7 @@ public interface Buffer { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Draw the pixel in (x, y). |    * Draw the pixel in (x, y). | ||||||
|  |    * | ||||||
|    * @param x X coordinate |    * @param x X coordinate | ||||||
|    * @param y Y coordinate |    * @param y Y coordinate | ||||||
|    */ |    */ | ||||||
| @@ -49,6 +51,7 @@ public interface Buffer { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Get all the pixels. |    * Get all the pixels. | ||||||
|  |    * | ||||||
|    * @return pixel list |    * @return pixel list | ||||||
|    */ |    */ | ||||||
|   Pixel[] getPixels(); |   Pixel[] getPixels(); | ||||||
|   | |||||||
| @@ -23,9 +23,6 @@ | |||||||
|  |  | ||||||
| package com.iluwatar.doublebuffer; | package com.iluwatar.doublebuffer; | ||||||
|  |  | ||||||
| import org.slf4j.Logger; |  | ||||||
| import org.slf4j.LoggerFactory; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * FrameBuffer implementation class. |  * FrameBuffer implementation class. | ||||||
|  */ |  */ | ||||||
|   | |||||||
| @@ -23,12 +23,11 @@ | |||||||
|  |  | ||||||
| package com.iluwatar.doublebuffer; | package com.iluwatar.doublebuffer; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
| import org.apache.commons.lang3.tuple.Pair; | import org.apache.commons.lang3.tuple.Pair; | ||||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Scene class. Render the output frame. |  * Scene class. Render the output frame. | ||||||
|  */ |  */ | ||||||
| @@ -55,6 +54,7 @@ public class Scene { | |||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Draw the next frame. |    * Draw the next frame. | ||||||
|  |    * | ||||||
|    * @param coordinateList list of pixels of which the color should be black |    * @param coordinateList list of pixels of which the color should be black | ||||||
|    */ |    */ | ||||||
|   public void draw(List<Pair<Integer, Integer>> coordinateList) { |   public void draw(List<Pair<Integer, Integer>> coordinateList) { | ||||||
|   | |||||||
| @@ -23,31 +23,29 @@ | |||||||
|  |  | ||||||
| package com.iluwatar.doublechecked.locking; | package com.iluwatar.doublechecked.locking; | ||||||
|  |  | ||||||
| import org.slf4j.Logger; |  | ||||||
| import org.slf4j.LoggerFactory; |  | ||||||
|  |  | ||||||
| import java.util.concurrent.ExecutorService; | import java.util.concurrent.ExecutorService; | ||||||
| import java.util.concurrent.Executors; | import java.util.concurrent.Executors; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  | ||||||
|  * Double Checked Locking is a concurrency design pattern used to reduce the overhead of acquiring a |  * Double Checked Locking is a concurrency design pattern used to reduce the overhead of acquiring a | ||||||
|  * lock by first testing the locking criterion (the "lock hint") without actually acquiring the |  * lock by first testing the locking criterion (the "lock hint") without actually acquiring the | ||||||
|  * lock. Only if the locking criterion check indicates that locking is required does the actual |  * lock. Only if the locking criterion check indicates that locking is required does the actual | ||||||
|  * locking logic proceed. |  * locking logic proceed. | ||||||
|  * <p> |  | ||||||
|  * In {@link Inventory} we store the items with a given size. However, we do not store more items |  | ||||||
|  * than the inventory size. To address concurrent access problems we use double checked locking to |  | ||||||
|  * add item to inventory. In this method, the thread which gets the lock first adds the item. |  | ||||||
|  * |  * | ||||||
|  |  * <p>In {@link Inventory} we store the items with a given size. However, we do not store more | ||||||
|  |  * items than the inventory size. To address concurrent access problems we use double checked | ||||||
|  |  * locking to add item to inventory. In this method, the thread which gets the lock first adds the | ||||||
|  |  * item. | ||||||
|  */ |  */ | ||||||
| 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 | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -23,19 +23,16 @@ | |||||||
|  |  | ||||||
| package com.iluwatar.doublechecked.locking; | package com.iluwatar.doublechecked.locking; | ||||||
|  |  | ||||||
| import org.slf4j.Logger; |  | ||||||
| import org.slf4j.LoggerFactory; |  | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.concurrent.locks.Lock; | import java.util.concurrent.locks.Lock; | ||||||
| import java.util.concurrent.locks.ReentrantLock; | import java.util.concurrent.locks.ReentrantLock; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * Inventory. | ||||||
|  * Inventory |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class Inventory { | public class Inventory { | ||||||
|  |  | ||||||
| @@ -46,7 +43,7 @@ public class Inventory { | |||||||
|   private final Lock lock; |   private final Lock lock; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Constructor |    * Constructor. | ||||||
|    */ |    */ | ||||||
|   public Inventory(int inventorySize) { |   public Inventory(int inventorySize) { | ||||||
|     this.inventorySize = inventorySize; |     this.inventorySize = inventorySize; | ||||||
| @@ -55,7 +52,7 @@ public class Inventory { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Add item |    * Add item. | ||||||
|    */ |    */ | ||||||
|   public boolean addItem(Item item) { |   public boolean addItem(Item item) { | ||||||
|     if (items.size() < inventorySize) { |     if (items.size() < inventorySize) { | ||||||
| @@ -63,7 +60,8 @@ public class Inventory { | |||||||
|       try { |       try { | ||||||
|         if (items.size() < inventorySize) { |         if (items.size() < inventorySize) { | ||||||
|           items.add(item); |           items.add(item); | ||||||
|           LOGGER.info("{}: items.size()={}, inventorySize={}", Thread.currentThread(), items.size(), inventorySize); |           LOGGER.info("{}: items.size()={}, inventorySize={}", Thread.currentThread(), items | ||||||
|  |               .size(), inventorySize); | ||||||
|           return true; |           return true; | ||||||
|         } |         } | ||||||
|       } finally { |       } finally { | ||||||
| @@ -74,7 +72,7 @@ public class Inventory { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Get all the items in the inventory |    * Get all the items in the inventory. | ||||||
|    * |    * | ||||||
|    * @return All the items of the inventory, as an unmodifiable list |    * @return All the items of the inventory, as an unmodifiable list | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -24,9 +24,7 @@ | |||||||
| package com.iluwatar.doublechecked.locking; | package com.iluwatar.doublechecked.locking; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * Item. | ||||||
|  * Item |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class Item { | public class Item { | ||||||
| } | } | ||||||
|   | |||||||
| @@ -23,38 +23,37 @@ | |||||||
|  |  | ||||||
| package com.iluwatar.doubledispatch; | package com.iluwatar.doubledispatch; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  |  * When a message with a parameter is sent to an object, the resultant behaviour is defined by the | ||||||
|  |  * implementation of that method in the receiver. Sometimes the behaviour must also be determined by | ||||||
|  |  * the type of the parameter. | ||||||
|  * |  * | ||||||
|  * When a message with a parameter is sent to an object, the resultant behaviour is defined by the implementation of |  * <p>One way to implement this would be to create multiple instanceof-checks for the methods | ||||||
|  * that method in the receiver. Sometimes the behaviour must also be determined by the type of the parameter. |  * parameter. However, this creates a maintenance issue. When new types are added we would also need | ||||||
|  * <p> |  * to change the method's implementation and add a new instanceof-check. This violates the single | ||||||
|  * One way to implement this would be to create multiple instanceof-checks for the methods parameter. However, this |  * responsibility principle - a class should have only one reason to change. | ||||||
|  * creates a maintenance issue. When new types are added we would also need to change the method's implementation and |  | ||||||
|  * add a new instanceof-check. This violates the single responsibility principle - a class should have only one reason |  | ||||||
|  * to change. |  | ||||||
|  * <p> |  | ||||||
|  * Instead of the instanceof-checks a better way is to make another virtual call on the parameter object. This way new |  | ||||||
|  * functionality can be easily added without the need to modify existing implementation (open-closed principle). |  | ||||||
|  * <p> |  | ||||||
|  * In this example we have hierarchy of objects ({@link GameObject}) that can collide to each other. Each object has its |  | ||||||
|  * own coordinates which are checked against the other objects' coordinates. If there is an overlap, then the objects |  | ||||||
|  * collide utilizing the Double Dispatch pattern. |  | ||||||
|  * |  * | ||||||
|  |  * <p>Instead of the instanceof-checks a better way is to make another virtual call on the | ||||||
|  |  * parameter object. This way new functionality can be easily added without the need to modify | ||||||
|  |  * existing implementation (open-closed principle). | ||||||
|  |  * | ||||||
|  |  * <p>In this example we have hierarchy of objects ({@link GameObject}) that can collide to each | ||||||
|  |  * other. Each object has its own coordinates which are checked against the other objects' | ||||||
|  |  * coordinates. If there is an overlap, then the objects collide utilizing the Double Dispatch | ||||||
|  |  * pattern. | ||||||
|  */ |  */ | ||||||
| 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 |    * @param args command line args | ||||||
|    *          command line args |  | ||||||
|    */ |    */ | ||||||
|   public static void main(String[] args) { |   public static void main(String[] args) { | ||||||
|     // initialize game objects and print their status |     // initialize game objects and print their status | ||||||
|   | |||||||
| @@ -24,9 +24,7 @@ | |||||||
| package com.iluwatar.doubledispatch; | package com.iluwatar.doubledispatch; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * Flaming asteroid game object. | ||||||
|  * Flaming asteroid game object |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class FlamingAsteroid extends Meteoroid { | public class FlamingAsteroid extends Meteoroid { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,9 +24,7 @@ | |||||||
| package com.iluwatar.doubledispatch; | package com.iluwatar.doubledispatch; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  | ||||||
|  * Game objects have coordinates and some other status information. |  * Game objects have coordinates and some other status information. | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public abstract class GameObject extends Rectangle { | public abstract class GameObject extends Rectangle { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,15 +23,12 @@ | |||||||
|  |  | ||||||
| package com.iluwatar.doubledispatch; | package com.iluwatar.doubledispatch; | ||||||
|  |  | ||||||
|  | import com.iluwatar.doubledispatch.constants.AppConstants; | ||||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import com.iluwatar.doubledispatch.constants.AppConstants; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * Meteoroid game object. | ||||||
|  * Meteoroid game object |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class Meteoroid extends GameObject { | public class Meteoroid extends GameObject { | ||||||
|  |  | ||||||
| @@ -48,12 +45,14 @@ public class Meteoroid extends GameObject { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void collisionResolve(FlamingAsteroid asteroid) { |   public void collisionResolve(FlamingAsteroid asteroid) { | ||||||
|     LOGGER.info(AppConstants.HITS, asteroid.getClass().getSimpleName(), this.getClass().getSimpleName()); |     LOGGER.info(AppConstants.HITS, asteroid.getClass().getSimpleName(), this.getClass() | ||||||
|  |         .getSimpleName()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void collisionResolve(Meteoroid meteoroid) { |   public void collisionResolve(Meteoroid meteoroid) { | ||||||
|     LOGGER.info(AppConstants.HITS, meteoroid.getClass().getSimpleName(), this.getClass().getSimpleName()); |     LOGGER.info(AppConstants.HITS, meteoroid.getClass().getSimpleName(), this.getClass() | ||||||
|  |         .getSimpleName()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   | |||||||
| @@ -24,9 +24,7 @@ | |||||||
| package com.iluwatar.doubledispatch; | package com.iluwatar.doubledispatch; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  | ||||||
|  * Rectangle has coordinates and can be checked for overlap against other Rectangles. |  * Rectangle has coordinates and can be checked for overlap against other Rectangles. | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class Rectangle { | public class Rectangle { | ||||||
|  |  | ||||||
| @@ -36,7 +34,7 @@ public class Rectangle { | |||||||
|   private int bottom; |   private int bottom; | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Constructor |    * Constructor. | ||||||
|    */ |    */ | ||||||
|   public Rectangle(int left, int top, int right, int bottom) { |   public Rectangle(int left, int top, int right, int bottom) { | ||||||
|     this.left = left; |     this.left = left; | ||||||
|   | |||||||
| @@ -24,9 +24,7 @@ | |||||||
| package com.iluwatar.doubledispatch; | package com.iluwatar.doubledispatch; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * Space station ISS game object. | ||||||
|  * Space station ISS game object |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class SpaceStationIss extends SpaceStationMir { | public class SpaceStationIss extends SpaceStationMir { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,15 +23,12 @@ | |||||||
|  |  | ||||||
| package com.iluwatar.doubledispatch; | package com.iluwatar.doubledispatch; | ||||||
|  |  | ||||||
|  | import com.iluwatar.doubledispatch.constants.AppConstants; | ||||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
| import com.iluwatar.doubledispatch.constants.AppConstants; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * Space station Mir game object. | ||||||
|  * Space station Mir game object |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class SpaceStationMir extends GameObject { | public class SpaceStationMir extends GameObject { | ||||||
|  |  | ||||||
| @@ -48,8 +45,10 @@ public class SpaceStationMir extends GameObject { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void collisionResolve(FlamingAsteroid asteroid) { |   public void collisionResolve(FlamingAsteroid asteroid) { | ||||||
|     LOGGER.info(AppConstants.HITS," {} is damaged! {} is set on fire!", asteroid.getClass().getSimpleName(), |     LOGGER.info(AppConstants.HITS, " {} is damaged! {} is set on fire!", asteroid.getClass() | ||||||
|         this.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass().getSimpleName()); |             .getSimpleName(), | ||||||
|  |         this.getClass().getSimpleName(), this.getClass().getSimpleName(), this.getClass() | ||||||
|  |             .getSimpleName()); | ||||||
|     setDamaged(true); |     setDamaged(true); | ||||||
|     setOnFire(true); |     setOnFire(true); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -24,9 +24,7 @@ | |||||||
| package com.iluwatar.doubledispatch.constants; | package com.iluwatar.doubledispatch.constants; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  |  * Constants class to define all constants. | ||||||
|  * Constants class to define all constants |  | ||||||
|  * |  | ||||||
|  */ |  */ | ||||||
| public class AppConstants { | public class AppConstants { | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user