diff --git a/core-java/pom.xml b/core-java/pom.xml
index 73b1c22ed8..422965a0ed 100644
--- a/core-java/pom.xml
+++ b/core-java/pom.xml
@@ -80,7 +80,11 @@
-
+
+ log4j
+ log4j
+ 1.2.17
+
org.slf4j
slf4j-api
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java
new file mode 100644
index 0000000000..0d69d0e7ec
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java
@@ -0,0 +1,13 @@
+package com.baeldung.designpatterns.adapter;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class AdapterPatternDriver {
+
+ public static void main(String args[]) {
+ LuxuryCarsSpeedAdapter luxuryCars = new LuxuryCarsSpeedAdapterImpl();
+ LOG.info("Bugatti Veyron Super Sport's top speed is " + luxuryCars.bugattiVeyronInKMPH() + " Kmph.");
+ LOG.info("McLaren F1 top speed is " + luxuryCars.mcLarenInKMPH() + " Kmph.");
+ LOG.info("Aston Martin One-77 top speed is " + luxuryCars.astonMartinInKMPH() + " Kmph.");
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeed.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeed.java
new file mode 100644
index 0000000000..278329b994
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeed.java
@@ -0,0 +1,15 @@
+package com.baeldung.designpatterns.adapter;
+
+public class LuxuryCarsSpeed {
+ public double bugattiVeyronInMPH() {
+ return 268;
+ }
+
+ public double mcLarenInMPH() {
+ return 241;
+ }
+
+ public double astonMartinInMPH() {
+ return 220;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapter.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapter.java
new file mode 100644
index 0000000000..84f7be2729
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapter.java
@@ -0,0 +1,7 @@
+package com.baeldung.designpatterns.adapter;
+
+public interface LuxuryCarsSpeedAdapter {
+ public double bugattiVeyronInKMPH();
+ public double mcLarenInKMPH();
+ public double astonMartinInKMPH();
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapterImpl.java b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapterImpl.java
new file mode 100644
index 0000000000..2767b78e38
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/adapter/LuxuryCarsSpeedAdapterImpl.java
@@ -0,0 +1,26 @@
+package com.baeldung.designpatterns.adapter;
+
+public class LuxuryCarsSpeedAdapterImpl extends LuxuryCarsSpeed implements LuxuryCarsSpeedAdapter {
+
+ @Override
+ public double bugattiVeyronInKMPH() {
+ double mph = super.bugattiVeyronInMPH();
+ return convertMPHtoKMPH(mph);
+ }
+
+ @Override
+ public double mcLarenInKMPH() {
+ double mph = super.mcLarenInMPH();
+ return convertMPHtoKMPH(mph);
+ }
+
+ @Override
+ public double astonMartinInKMPH() {
+ double mph = super.astonMartinInMPH();
+ return convertMPHtoKMPH(mph);
+ }
+
+ private double convertMPHtoKMPH(double mph) {
+ return mph * 1.60934;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java
new file mode 100644
index 0000000000..97a4a9508c
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java
@@ -0,0 +1,12 @@
+package com.baeldung.designpatterns.bridge;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class Blue implements Color {
+
+ @Override
+ public void fillColor() {
+ LOG.info("Color : Blue");
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java
new file mode 100644
index 0000000000..921deadcac
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java
@@ -0,0 +1,14 @@
+package com.baeldung.designpatterns.bridge;
+
+public class BridgePatternDriver {
+
+ public static void main(String[] args) {
+ //a square with red color
+ Shape square = new Square(new Red());
+ square.drawShape();
+
+ //a triangle with blue color
+ Shape triangle = new Triangle(new Blue());
+ triangle.drawShape();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java
new file mode 100644
index 0000000000..91d2b01609
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java
@@ -0,0 +1,5 @@
+package com.baeldung.designpatterns.bridge;
+
+public interface Color {
+ public void fillColor();
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java
new file mode 100644
index 0000000000..8c22a94f00
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java
@@ -0,0 +1,12 @@
+package com.baeldung.designpatterns.bridge;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class Red implements Color {
+
+ @Override
+ public void fillColor() {
+ LOG.info("Color : Red");
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java
new file mode 100644
index 0000000000..c4daf7a821
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java
@@ -0,0 +1,11 @@
+package com.baeldung.designpatterns.bridge;
+
+public abstract class Shape {
+ protected Color color;
+
+ public Shape(Color color) {
+ this.color = color;
+ }
+
+ abstract public void drawShape();
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java
new file mode 100644
index 0000000000..6b377197eb
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java
@@ -0,0 +1,16 @@
+package com.baeldung.designpatterns.bridge;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class Square extends Shape {
+
+ public Square(Color color) {
+ super(color);
+ }
+
+ @Override
+ public void drawShape() {
+ LOG.info("Square drawn. ");
+ color.fillColor();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java
new file mode 100644
index 0000000000..900e78cf2b
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java
@@ -0,0 +1,16 @@
+package com.baeldung.designpatterns.bridge;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class Triangle extends Shape {
+
+ public Triangle(Color color) {
+ super(color);
+ }
+
+ @Override
+ public void drawShape() {
+ LOG.info("Triangle drawn. ");
+ color.fillColor();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/BubbleLights.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/BubbleLights.java
new file mode 100644
index 0000000000..881add8b21
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/BubbleLights.java
@@ -0,0 +1,16 @@
+package com.baeldung.designpatterns.decorator;
+
+public class BubbleLights extends TreeDecorator {
+
+ public BubbleLights(ChristmasTree tree) {
+ super(tree);
+ }
+
+ public String decorate() {
+ return super.decorate() + decorateWithBubbleLights();
+ }
+
+ private String decorateWithBubbleLights() {
+ return " with Bubble Lights";
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java
new file mode 100644
index 0000000000..80a0865567
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java
@@ -0,0 +1,5 @@
+package com.baeldung.designpatterns.decorator;
+
+public interface ChristmasTree {
+ public String decorate();
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTreeImpl.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTreeImpl.java
new file mode 100644
index 0000000000..9241fd59db
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTreeImpl.java
@@ -0,0 +1,10 @@
+package com.baeldung.designpatterns.decorator;
+
+public class ChristmasTreeImpl implements ChristmasTree {
+
+ @Override
+ public String decorate() {
+ return "Christmas tree";
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/DecoratorPatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/DecoratorPatternDriver.java
new file mode 100644
index 0000000000..f70991da6b
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/DecoratorPatternDriver.java
@@ -0,0 +1,20 @@
+package com.baeldung.designpatterns.decorator;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+
+public class DecoratorPatternDriver {
+
+ public static void main(String[] args) {
+ //christmas tree with just one Garland
+ ChristmasTree tree1 = new Garland(new ChristmasTreeImpl());
+ LOG.info(tree1.decorate());
+
+ //christmas tree with two Garlands and one Bubble lights
+ ChristmasTree tree2 = new BubbleLights(new Garland(
+ new Garland(new ChristmasTreeImpl()))
+ );
+ LOG.info(tree2.decorate());
+
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/Garland.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/Garland.java
new file mode 100644
index 0000000000..d2efd6e451
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/Garland.java
@@ -0,0 +1,16 @@
+package com.baeldung.designpatterns.decorator;
+
+public class Garland extends TreeDecorator {
+
+ public Garland(ChristmasTree tree) {
+ super(tree);
+ }
+
+ public String decorate() {
+ return super.decorate() + decorateWithGarland();
+ }
+
+ private String decorateWithGarland() {
+ return " with Garland";
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/TreeDecorator.java b/core-java/src/main/java/com/baeldung/designpatterns/decorator/TreeDecorator.java
new file mode 100644
index 0000000000..5427d2ac7e
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/decorator/TreeDecorator.java
@@ -0,0 +1,15 @@
+package com.baeldung.designpatterns.decorator;
+
+public abstract class TreeDecorator implements ChristmasTree {
+ private ChristmasTree tree;
+
+ public TreeDecorator(ChristmasTree tree) {
+ this.tree = tree;
+ }
+
+ @Override
+ public String decorate() {
+ return tree.decorate();
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java
new file mode 100644
index 0000000000..96a6bfb878
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java
@@ -0,0 +1,5 @@
+package com.baeldung.designpatterns.proxy;
+
+public interface ExpensiveObject {
+ public void process();
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectImpl.java b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectImpl.java
new file mode 100644
index 0000000000..7014d3811c
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectImpl.java
@@ -0,0 +1,20 @@
+package com.baeldung.designpatterns.proxy;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;;
+
+public class ExpensiveObjectImpl implements ExpensiveObject {
+
+ public ExpensiveObjectImpl() {
+ heavyInitialConfiguration();
+ }
+
+ @Override
+ public void process() {
+ LOG.info("processing complete.");
+ }
+
+ private void heavyInitialConfiguration() {
+ LOG.info("Loading initial configuration...");
+ }
+
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectProxy.java b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectProxy.java
new file mode 100644
index 0000000000..f36e688c90
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectProxy.java
@@ -0,0 +1,13 @@
+package com.baeldung.designpatterns.proxy;
+
+public class ExpensiveObjectProxy implements ExpensiveObject{
+ private static ExpensiveObject object;
+
+ @Override
+ public void process() {
+ if(object == null) {
+ object = new ExpensiveObjectImpl();
+ }
+ object.process();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ProxyPatternDriver.java b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ProxyPatternDriver.java
new file mode 100644
index 0000000000..088b069e28
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/proxy/ProxyPatternDriver.java
@@ -0,0 +1,9 @@
+package com.baeldung.designpatterns.proxy;
+
+public class ProxyPatternDriver {
+ public static void main(String[] args) {
+ ExpensiveObject object = new ExpensiveObjectProxy();
+ object.process();
+ object.process();
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/ClassSingleton.java b/core-java/src/main/java/com/baeldung/designpatterns/singleton/ClassSingleton.java
new file mode 100644
index 0000000000..0fc86e30a7
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/singleton/ClassSingleton.java
@@ -0,0 +1,28 @@
+package com.baeldung.designpatterns.singleton;
+
+public class ClassSingleton {
+
+ private static ClassSingleton INSTANCE;
+ private String info = "Initial class info";
+
+ private ClassSingleton(){
+ }
+
+ public static ClassSingleton getInstance(){
+ if(INSTANCE == null){
+ INSTANCE = new ClassSingleton();
+ }
+
+ return INSTANCE;
+ }
+
+ // getters and setters
+
+ public String getInfo() {
+ return info;
+ }
+
+ public void setInfo(String info) {
+ this.info = info;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/EnumSingleton.java b/core-java/src/main/java/com/baeldung/designpatterns/singleton/EnumSingleton.java
new file mode 100644
index 0000000000..f75484477b
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/singleton/EnumSingleton.java
@@ -0,0 +1,26 @@
+package com.baeldung.designpatterns.singleton;
+
+public enum EnumSingleton {
+
+ INSTANCE("Initial enum info"); //Name of the single instance
+
+ private String info;
+
+ private EnumSingleton(String info) {
+ this.info = info;
+ }
+
+ public EnumSingleton getInstance(){
+ return INSTANCE;
+ }
+
+ //getters and setters
+
+ public String getInfo() {
+ return info;
+ }
+
+ public void setInfo(String info) {
+ this.info = info;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/Sandbox.java b/core-java/src/main/java/com/baeldung/designpatterns/singleton/Sandbox.java
new file mode 100644
index 0000000000..f8ca2ffa78
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/singleton/Sandbox.java
@@ -0,0 +1,32 @@
+package com.baeldung.designpatterns.singleton;
+
+public class Sandbox {
+
+ public static void main(String[] args) {
+
+ //Class singleton
+
+ ClassSingleton classSingleton1 = ClassSingleton.getInstance();
+ //OurSingleton object1 = new OurSingleton(); // The constructor OurSingleton() is not visible
+
+ System.out.println(classSingleton1.getInfo()); //Initial class info
+
+ ClassSingleton classSingleton2 = ClassSingleton.getInstance();
+ classSingleton2.setInfo("New class info");
+
+ System.out.println(classSingleton1.getInfo()); //New class info
+ System.out.println(classSingleton2.getInfo()); //New class info
+
+ //Enum singleton
+
+ EnumSingleton enumSingleton1 = EnumSingleton.INSTANCE.getInstance();
+
+ System.out.println(enumSingleton1.getInfo()); //Initial enum info
+
+ EnumSingleton enumSingleton2 = EnumSingleton.INSTANCE.getInstance();
+ enumSingleton2.setInfo("New enum info");
+
+ System.out.println(enumSingleton1.getInfo()); //New enum info
+ System.out.println(enumSingleton2.getInfo()); //New enum info
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/designpatterns/util/LogerUtil.java b/core-java/src/main/java/com/baeldung/designpatterns/util/LogerUtil.java
new file mode 100644
index 0000000000..f7b6e4f3e9
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/designpatterns/util/LogerUtil.java
@@ -0,0 +1,35 @@
+package com.baeldung.designpatterns.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+public class LogerUtil {
+
+ public final static Logger LOG = Logger.getLogger("GLOBAL");
+
+ static {
+ configuration();
+ }
+
+ private static void configuration() {
+ Properties props = new Properties();
+ try {
+ props.load(
+ new BufferedReader(
+ new InputStreamReader(
+ LogerUtil.class.getResourceAsStream("/log4jstructuraldp.properties")
+ )
+ )
+ );
+ } catch (IOException e) {
+ System.out.println("log4jstructuraldp.properties file not configured properly");
+ System.exit(0);
+ }
+ PropertyConfigurator.configure(props);
+ }
+}
diff --git a/core-java/src/main/resources/log4jstructuraldp.properties b/core-java/src/main/resources/log4jstructuraldp.properties
new file mode 100644
index 0000000000..5bc2bfe4b9
--- /dev/null
+++ b/core-java/src/main/resources/log4jstructuraldp.properties
@@ -0,0 +1,9 @@
+
+# Root logger
+log4j.rootLogger=INFO, file, stdout
+
+# Write to console
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java
new file mode 100644
index 0000000000..fb483a8a68
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java
@@ -0,0 +1,20 @@
+package com.baeldung.designpatterns;
+
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import com.baeldung.designpatterns.adapter.LuxuryCarsSpeedAdapter;
+import com.baeldung.designpatterns.adapter.LuxuryCarsSpeedAdapterImpl;
+
+public class AdapterPatternIntegrationTest {
+ @Test
+ public void givenLuxuryCarsAdapter_WhenConvertingMPHToKMPH_thenSuccessfullyConverted() {
+ LuxuryCarsSpeedAdapter luxuryCars = new LuxuryCarsSpeedAdapterImpl();
+ assertEquals(luxuryCars.bugattiVeyronInKMPH(), 431.30312, 0.00001);
+ assertEquals(luxuryCars.mcLarenInKMPH(), 387.85094, 0.00001);
+ assertEquals(luxuryCars.astonMartinInKMPH(), 354.0548, 0.00001);
+ }
+}
+
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java
new file mode 100644
index 0000000000..56a7a704f2
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java
@@ -0,0 +1,52 @@
+package com.baeldung.designpatterns;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.apache.log4j.spi.LoggingEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.baeldung.designpatterns.bridge.Blue;
+import com.baeldung.designpatterns.bridge.Red;
+import com.baeldung.designpatterns.bridge.Shape;
+import com.baeldung.designpatterns.bridge.Square;
+import com.baeldung.designpatterns.bridge.Triangle;
+
+public class BridgePatternIntegrationTest {
+ public static TestAppenderDP appender;
+
+ @Before
+ public void setUp() {
+ appender = new TestAppenderDP();
+ LOG.addAppender(appender);
+ }
+
+ @Test
+ public void whenBridgePatternInvoked_thenConfigSuccess() {
+ //a square with red color
+ Shape square = new Square(new Red());
+ square.drawShape();
+
+ //a triangle with blue color
+ Shape triangle = new Triangle(new Blue());
+ triangle.drawShape();
+
+ final List log = appender.getLog();
+
+ assertThat((String) log.get(0).getMessage(), is("Square drawn. "));
+ assertThat((String) log.get(1).getMessage(), is("Color : Red"));
+ assertThat((String) log.get(2).getMessage(), is("Triangle drawn. "));
+ assertThat((String) log.get(3).getMessage(), is("Color : Blue"));
+ }
+
+ @After
+ public void tearDown() {
+ LOG.removeAppender(appender);
+ }
+}
+
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java
new file mode 100644
index 0000000000..b3b3f988f1
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java
@@ -0,0 +1,28 @@
+package com.baeldung.designpatterns;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.baeldung.designpatterns.decorator.BubbleLights;
+import com.baeldung.designpatterns.decorator.ChristmasTree;
+import com.baeldung.designpatterns.decorator.ChristmasTreeImpl;
+import com.baeldung.designpatterns.decorator.Garland;
+
+public class DecoratorPatternIntegrationTest {
+ private ChristmasTree tree;
+
+ @Test
+ public void givenDecoratorPattern_WhenDecoratorsInjectedAtRuntime_thenConfigSuccess() {
+ //christmas tree with just one Garland
+ tree = new Garland(new ChristmasTreeImpl());
+ assertEquals(tree.decorate(), "Christmas tree with Garland");
+
+ //christmas tree with two Garlands and one Bubble lights
+ tree = new BubbleLights(new Garland(
+ new Garland(new ChristmasTreeImpl()))
+ );
+ assertEquals(tree.decorate(), "Christmas tree with Garland with Garland with Bubble Lights");
+ }
+}
+
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/ProxyPatternIntegrationTest.java b/core-java/src/test/java/com/baeldung/designpatterns/ProxyPatternIntegrationTest.java
new file mode 100644
index 0000000000..7fa95b31d7
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/ProxyPatternIntegrationTest.java
@@ -0,0 +1,44 @@
+package com.baeldung.designpatterns;
+
+import static com.baeldung.designpatterns.util.LogerUtil.LOG;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.apache.log4j.spi.LoggingEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.baeldung.designpatterns.proxy.ExpensiveObject;
+import com.baeldung.designpatterns.proxy.ExpensiveObjectProxy;
+
+public class ProxyPatternIntegrationTest {
+ public static TestAppenderDP appender;
+
+ @Before
+ public void setUp() {
+ appender = new TestAppenderDP();
+ LOG.addAppender(appender);
+ }
+
+ @Test
+ public void givenExpensiveObjectProxy_WhenObjectInitialized_thenInitializedOnlyOnce() {
+ ExpensiveObject object = new ExpensiveObjectProxy();
+ object.process();
+ object.process();
+
+ final List log = appender.getLog();
+
+ assertThat((String) log.get(0).getMessage(), is("Loading initial configuration..."));
+ assertThat((String) log.get(1).getMessage(), is("processing complete."));
+ assertThat((String) log.get(2).getMessage(), is("processing complete."));
+ }
+
+ @After
+ public void tearDown() {
+ LOG.removeAppender(appender);
+ }
+}
+
diff --git a/core-java/src/test/java/com/baeldung/designpatterns/TestAppenderDP.java b/core-java/src/test/java/com/baeldung/designpatterns/TestAppenderDP.java
new file mode 100644
index 0000000000..613c26fa13
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/designpatterns/TestAppenderDP.java
@@ -0,0 +1,29 @@
+package com.baeldung.designpatterns;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.AppenderSkeleton;
+import org.apache.log4j.spi.LoggingEvent;
+
+public class TestAppenderDP extends AppenderSkeleton {
+ private final List log = new ArrayList();
+
+ @Override
+ public boolean requiresLayout() {
+ return false;
+ }
+
+ @Override
+ protected void append(final LoggingEvent loggingEvent) {
+ log.add(loggingEvent);
+ }
+
+ @Override
+ public void close() {
+ }
+
+ public List getLog() {
+ return new ArrayList(log);
+ }
+}
\ No newline at end of file
diff --git a/libraries/README.md b/libraries/README.md
index 86baa39045..0e58628118 100644
--- a/libraries/README.md
+++ b/libraries/README.md
@@ -28,6 +28,7 @@
- [Guide to the HyperLogLog Algorithm](http://www.baeldung.com/java-hyperloglog)
- [Introduction to Neuroph](http://www.baeldung.com/intro-to-neuroph)
- [Guide to Apache Commons CircularFifoQueue](http://www.baeldung.com/commons-circular-fifo-queue)
+- [Quick Guide to RSS with Rome](http://www.baeldung.com/rome-rss)
The libraries module contains examples related to small libraries that are relatively easy to use and does not require any separate module of its own.
diff --git a/noexception/README.md b/noexception/README.md
new file mode 100644
index 0000000000..d840191369
--- /dev/null
+++ b/noexception/README.md
@@ -0,0 +1,2 @@
+### Relevant Articles:
+- [Introduction to NoException](http://www.baeldung.com/intrduction-to-noexception)
diff --git a/noexception/pom.xml b/noexception/pom.xml
new file mode 100644
index 0000000000..64c0591fda
--- /dev/null
+++ b/noexception/pom.xml
@@ -0,0 +1,23 @@
+
+ 4.0.0
+
+ com.baeldung
+ noexception
+ 1.0
+ noexception
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ com.machinezoo.noexception
+ noexception
+ 1.1.0
+
+
+
diff --git a/noexception/src/main/java/com/baeldung/noexception/CustomExceptionHandler.java b/noexception/src/main/java/com/baeldung/noexception/CustomExceptionHandler.java
new file mode 100644
index 0000000000..59e13efaa0
--- /dev/null
+++ b/noexception/src/main/java/com/baeldung/noexception/CustomExceptionHandler.java
@@ -0,0 +1,24 @@
+package com.baeldung.noexception;
+
+import com.machinezoo.noexception.ExceptionHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CustomExceptionHandler extends ExceptionHandler {
+
+ private Logger logger = LoggerFactory.getLogger(CustomExceptionHandler.class);
+
+ @Override
+ public boolean handle(Throwable throwable) {
+
+ if (throwable.getClass()
+ .isAssignableFrom(RuntimeException.class)
+ || throwable.getClass()
+ .isAssignableFrom(Error.class)) {
+ return false;
+ } else {
+ logger.error("Caught Exception ", throwable);
+ return true;
+ }
+ }
+}
diff --git a/noexception/src/test/java/com/baeldung/noexception/NoExceptionUnitTest.java b/noexception/src/test/java/com/baeldung/noexception/NoExceptionUnitTest.java
new file mode 100644
index 0000000000..690ea43520
--- /dev/null
+++ b/noexception/src/test/java/com/baeldung/noexception/NoExceptionUnitTest.java
@@ -0,0 +1,63 @@
+package com.baeldung.noexception;
+
+import com.machinezoo.noexception.Exceptions;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NoExceptionUnitTest {
+
+ private static Logger logger = LoggerFactory.getLogger(NoExceptionUnitTest.class);
+
+ @Test
+ public void whenStdExceptionHandling_thenCatchAndLog() {
+ try {
+ System.out.println("Result is " + Integer.parseInt("foobar"));
+ } catch (Throwable exception) {
+ logger.error("Caught exception:", exception);
+ }
+ }
+
+ @Test
+ public void whenDefaultNoException_thenCatchAndLog() {
+
+ Exceptions.log().run(() -> System.out.println("Result is " + Integer.parseInt("foobar")));
+ }
+
+ @Test
+ public void givenLogger_whenDefaultNoException_thenCatchAndLogWithClassName() {
+ System.out.println("Result is " + Exceptions.log(logger).get(() -> +Integer.parseInt("foobar")).orElse(-1));
+ }
+
+ @Test
+ public void givenLoggerAndMessage_whenDefaultNoException_thenCatchAndLogWithClassNameAndMessage() {
+ System.out.println("Result is " + Exceptions.log(logger, "Something went wrong:").get(() -> +Integer.parseInt("foobar")).orElse(-1));
+ }
+
+ @Test
+ public void givenDefaultValue_whenDefaultNoException_thenCatchAndLogPrintDefault() {
+ System.out.println("Result is " + Exceptions.log(logger, "Something went wrong:").get(() -> +Integer.parseInt("foobar")).orElse(-1));
+ }
+
+ @Test(expected = Error.class)
+ public void givenCustomHandler_whenError_thenRethrowError() {
+ CustomExceptionHandler customExceptionHandler = new CustomExceptionHandler();
+ customExceptionHandler.run(() -> throwError());
+ }
+
+ @Test
+ public void givenCustomHandler_whenException_thenCatchAndLog() {
+ CustomExceptionHandler customExceptionHandler = new CustomExceptionHandler();
+ customExceptionHandler.run(() -> throwException());
+ }
+
+ private static void throwError() {
+ throw new Error("This is very bad.");
+ }
+
+ private static void throwException() {
+ String testString = "foo";
+ testString.charAt(5);
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index f33d63bc48..8b3df8de0d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -106,6 +106,7 @@
mockito2
mocks
mustache
+ noexception
orika
diff --git a/spring-boot-property-exp/pom.xml b/spring-boot-property-exp/pom.xml
index f554bb5b99..0c54d57db1 100644
--- a/spring-boot-property-exp/pom.xml
+++ b/spring-boot-property-exp/pom.xml
@@ -24,8 +24,8 @@
- property-exp-default
- property-exp-custom
+ property-exp-default-config
+ property-exp-custom-config
diff --git a/spring-boot-property-exp/property-exp-custom/pom.xml b/spring-boot-property-exp/property-exp-custom-config/pom.xml
similarity index 100%
rename from spring-boot-property-exp/property-exp-custom/pom.xml
rename to spring-boot-property-exp/property-exp-custom-config/pom.xml
diff --git a/spring-boot-property-exp/property-exp-custom/src/main/java/com/baeldung/propertyexpansion/SpringBootPropertyExpansionApp.java b/spring-boot-property-exp/property-exp-custom-config/src/main/java/com/baeldung/propertyexpansion/SpringBootPropertyExpansionApp.java
similarity index 100%
rename from spring-boot-property-exp/property-exp-custom/src/main/java/com/baeldung/propertyexpansion/SpringBootPropertyExpansionApp.java
rename to spring-boot-property-exp/property-exp-custom-config/src/main/java/com/baeldung/propertyexpansion/SpringBootPropertyExpansionApp.java
diff --git a/spring-boot-property-exp/property-exp-custom/src/main/java/com/baeldung/propertyexpansion/components/PropertyLoggerBean.java b/spring-boot-property-exp/property-exp-custom-config/src/main/java/com/baeldung/propertyexpansion/components/PropertyLoggerBean.java
similarity index 100%
rename from spring-boot-property-exp/property-exp-custom/src/main/java/com/baeldung/propertyexpansion/components/PropertyLoggerBean.java
rename to spring-boot-property-exp/property-exp-custom-config/src/main/java/com/baeldung/propertyexpansion/components/PropertyLoggerBean.java
diff --git a/spring-boot-property-exp/property-exp-custom/src/main/resources/application.properties b/spring-boot-property-exp/property-exp-custom-config/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-property-exp/property-exp-custom/src/main/resources/application.properties
rename to spring-boot-property-exp/property-exp-custom-config/src/main/resources/application.properties
diff --git a/spring-boot-property-exp/property-exp-custom/src/main/resources/banner.txt b/spring-boot-property-exp/property-exp-custom-config/src/main/resources/banner.txt
similarity index 100%
rename from spring-boot-property-exp/property-exp-custom/src/main/resources/banner.txt
rename to spring-boot-property-exp/property-exp-custom-config/src/main/resources/banner.txt
diff --git a/spring-boot-property-exp/property-exp-default/build.gradle b/spring-boot-property-exp/property-exp-default-config/build.gradle
similarity index 100%
rename from spring-boot-property-exp/property-exp-default/build.gradle
rename to spring-boot-property-exp/property-exp-default-config/build.gradle
diff --git a/spring-boot-property-exp/property-exp-default/gradle.properties b/spring-boot-property-exp/property-exp-default-config/gradle.properties
similarity index 100%
rename from spring-boot-property-exp/property-exp-default/gradle.properties
rename to spring-boot-property-exp/property-exp-default-config/gradle.properties
diff --git a/spring-boot-property-exp/property-exp-default/pom.xml b/spring-boot-property-exp/property-exp-default-config/pom.xml
similarity index 100%
rename from spring-boot-property-exp/property-exp-default/pom.xml
rename to spring-boot-property-exp/property-exp-default-config/pom.xml
diff --git a/spring-boot-property-exp/property-exp-default/settings.gradle b/spring-boot-property-exp/property-exp-default-config/settings.gradle
similarity index 100%
rename from spring-boot-property-exp/property-exp-default/settings.gradle
rename to spring-boot-property-exp/property-exp-default-config/settings.gradle
diff --git a/spring-boot-property-exp/property-exp-default/src/main/java/com/baeldung/propertyexpansion/SpringBootPropertyExpansionApp.java b/spring-boot-property-exp/property-exp-default-config/src/main/java/com/baeldung/propertyexpansion/SpringBootPropertyExpansionApp.java
similarity index 100%
rename from spring-boot-property-exp/property-exp-default/src/main/java/com/baeldung/propertyexpansion/SpringBootPropertyExpansionApp.java
rename to spring-boot-property-exp/property-exp-default-config/src/main/java/com/baeldung/propertyexpansion/SpringBootPropertyExpansionApp.java
diff --git a/spring-boot-property-exp/property-exp-default/src/main/java/com/baeldung/propertyexpansion/components/PropertyLoggerBean.java b/spring-boot-property-exp/property-exp-default-config/src/main/java/com/baeldung/propertyexpansion/components/PropertyLoggerBean.java
similarity index 100%
rename from spring-boot-property-exp/property-exp-default/src/main/java/com/baeldung/propertyexpansion/components/PropertyLoggerBean.java
rename to spring-boot-property-exp/property-exp-default-config/src/main/java/com/baeldung/propertyexpansion/components/PropertyLoggerBean.java
diff --git a/spring-boot-property-exp/property-exp-default/src/main/resources/application.properties b/spring-boot-property-exp/property-exp-default-config/src/main/resources/application.properties
similarity index 100%
rename from spring-boot-property-exp/property-exp-default/src/main/resources/application.properties
rename to spring-boot-property-exp/property-exp-default-config/src/main/resources/application.properties
diff --git a/spring-boot-property-exp/property-exp-default/src/main/resources/banner.txt b/spring-boot-property-exp/property-exp-default-config/src/main/resources/banner.txt
similarity index 100%
rename from spring-boot-property-exp/property-exp-default/src/main/resources/banner.txt
rename to spring-boot-property-exp/property-exp-default-config/src/main/resources/banner.txt
diff --git a/spring-core/README.md b/spring-core/README.md
index 380b3138fe..b0d0b8408c 100644
--- a/spring-core/README.md
+++ b/spring-core/README.md
@@ -6,3 +6,4 @@
- [Constructor Injection in Spring with Lombok](http://www.baeldung.com/spring-injection-lombok)
- [A Quick Guide to Spring @Value](http://www.baeldung.com/spring-value-annotation)
- [Spring YAML Configuration](http://www.baeldung.com/spring-yaml)
+- [Using Spring @Value with Defaults](http://www.baeldung.com/spring-value-defaults)