From c52e12aa05edd5cb4c4e4caa095717d44ccf950c Mon Sep 17 00:00:00 2001 From: Ehsan Date: Fri, 13 Dec 2019 23:08:14 +0330 Subject: [PATCH 1/3] commits decorator design pattern. --- .../decorator/CompressingDecorator.java | 39 +++++++++++++++++++ .../structural/decorator/EmailSender.java | 12 ++++++ .../decorator/EncodingDecorator.java | 24 ++++++++++++ .../structural/decorator/Sender.java | 5 +++ .../structural/decorator/SenderDecorator.java | 17 ++++++++ 5 files changed, 97 insertions(+) create mode 100644 src/main/java/com/designpatterns/structural/decorator/CompressingDecorator.java create mode 100644 src/main/java/com/designpatterns/structural/decorator/EmailSender.java create mode 100644 src/main/java/com/designpatterns/structural/decorator/EncodingDecorator.java create mode 100644 src/main/java/com/designpatterns/structural/decorator/Sender.java create mode 100644 src/main/java/com/designpatterns/structural/decorator/SenderDecorator.java diff --git a/src/main/java/com/designpatterns/structural/decorator/CompressingDecorator.java b/src/main/java/com/designpatterns/structural/decorator/CompressingDecorator.java new file mode 100644 index 000000000000..b4a5da45f122 --- /dev/null +++ b/src/main/java/com/designpatterns/structural/decorator/CompressingDecorator.java @@ -0,0 +1,39 @@ +package com.designpatterns.structural.decorator; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.zip.GZIPOutputStream; + +/** + * this is one of the concrete decorators + */ +public class CompressingDecorator extends SenderDecorator { + + public CompressingDecorator(Sender sender) { + super(sender); + } + + @Override + public String send(String content) { + String compressedContent = new String(compressContent(content)); + super.send(compressedContent); + return compressedContent; + } + + private byte[] compressContent(String content) { + try{ + ByteArrayOutputStream baostream = new ByteArrayOutputStream(); + OutputStream outStream = new GZIPOutputStream(baostream); + outStream.write(content.getBytes("UTF-8")); + outStream.close(); + byte[] compressedBytes = baostream.toByteArray(); // toString not always possible + return compressedBytes; + } catch (IOException e) { + throw new RuntimeException("exception happened while compressing email content"); + + } + } + + +} diff --git a/src/main/java/com/designpatterns/structural/decorator/EmailSender.java b/src/main/java/com/designpatterns/structural/decorator/EmailSender.java new file mode 100644 index 000000000000..64e0d51c2fe9 --- /dev/null +++ b/src/main/java/com/designpatterns/structural/decorator/EmailSender.java @@ -0,0 +1,12 @@ +package com.designpatterns.structural.decorator; + +/** + * this is the class which should be decorated without any modification + */ +public class EmailSender implements Sender { + @Override + public String send(String content) { + System.out.println("sending \"" + content + "\" as email"); + return content; + } +} diff --git a/src/main/java/com/designpatterns/structural/decorator/EncodingDecorator.java b/src/main/java/com/designpatterns/structural/decorator/EncodingDecorator.java new file mode 100644 index 000000000000..8ffd1ff3ae1f --- /dev/null +++ b/src/main/java/com/designpatterns/structural/decorator/EncodingDecorator.java @@ -0,0 +1,24 @@ +package com.designpatterns.structural.decorator; + +import java.util.Base64; + +/** + * this is another concrete decorator. + */ +public class EncodingDecorator extends SenderDecorator { + + public EncodingDecorator(Sender sender) { + super(sender); + } + + @Override + public String send(String content) { + String encodedContent = encodeContent(content); + super.send(encodedContent); + return encodedContent; + } + + private String encodeContent(String content){ + return Base64.getEncoder().encodeToString(content.getBytes()); + } +} diff --git a/src/main/java/com/designpatterns/structural/decorator/Sender.java b/src/main/java/com/designpatterns/structural/decorator/Sender.java new file mode 100644 index 000000000000..cadb90cd5182 --- /dev/null +++ b/src/main/java/com/designpatterns/structural/decorator/Sender.java @@ -0,0 +1,5 @@ +package com.designpatterns.structural.decorator; + +public interface Sender { + String send(String content); +} diff --git a/src/main/java/com/designpatterns/structural/decorator/SenderDecorator.java b/src/main/java/com/designpatterns/structural/decorator/SenderDecorator.java new file mode 100644 index 000000000000..2903e69ce1cc --- /dev/null +++ b/src/main/java/com/designpatterns/structural/decorator/SenderDecorator.java @@ -0,0 +1,17 @@ +package com.designpatterns.structural.decorator; + +/** + * this is the base decorator. + */ +public class SenderDecorator implements Sender { + private Sender sender; + + public SenderDecorator(Sender sender) { + this.sender = sender; + } + + @Override + public String send(String content) { + return this.sender.send(content); + } +} From 59eb36e4abaf671ea41153bc873c302dd8c8f38a Mon Sep 17 00:00:00 2001 From: ehsan Date: Fri, 13 Dec 2019 23:57:49 +0330 Subject: [PATCH 2/3] commits tests for testing decorator pattern. --- .../decorator/DecoratorDemo.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/test/java/com/designpatterns/decorator/DecoratorDemo.java diff --git a/src/test/java/com/designpatterns/decorator/DecoratorDemo.java b/src/test/java/com/designpatterns/decorator/DecoratorDemo.java new file mode 100644 index 000000000000..08aaf02b0f7c --- /dev/null +++ b/src/test/java/com/designpatterns/decorator/DecoratorDemo.java @@ -0,0 +1,43 @@ +package com.designpatterns.decorator; + +import com.designpatterns.structural.decorator.EmailSender; +import com.designpatterns.structural.decorator.EncodingDecorator; +import com.designpatterns.structural.decorator.Sender; +import com.designpatterns.structural.decorator.SenderDecorator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Base64; + +public class DecoratorDemo { + + @Test + public void testDecorator_sendEmailAsPlainText() { + String message = "test message"; + EmailSender sender = new EmailSender(); + String content = sender.send(message); + + Assertions.assertEquals(content, message); + + } + + @Test + public void testDecorator_sendEmailAsEncodedTest() { + String message = "test message"; + Sender sender = new SenderDecorator( + new EncodingDecorator( + new EmailSender() + ) + ); + + String encodedContent = sender.send(message); + + Assertions.assertEquals( + new String(Base64.getDecoder().decode (encodedContent)), + message + ); + + + + } +} From 78f7a803eaafb0ee1770ce100f7be59905f583b1 Mon Sep 17 00:00:00 2001 From: ehsan Date: Sat, 14 Dec 2019 22:03:49 +0330 Subject: [PATCH 3/3] adds new test for testing encoding and compressing email. --- .../decorator/CompressingDecorator.java | 14 +++---- .../decorator/DecoratorDemo.java | 37 ++++++++++++++----- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/designpatterns/structural/decorator/CompressingDecorator.java b/src/main/java/com/designpatterns/structural/decorator/CompressingDecorator.java index b4a5da45f122..f1cea07b5437 100644 --- a/src/main/java/com/designpatterns/structural/decorator/CompressingDecorator.java +++ b/src/main/java/com/designpatterns/structural/decorator/CompressingDecorator.java @@ -16,22 +16,20 @@ public CompressingDecorator(Sender sender) { @Override public String send(String content) { - String compressedContent = new String(compressContent(content)); + byte[] compressedBytes = compressContent(content); + String compressedContent = new String(compressedBytes); super.send(compressedContent); return compressedContent; } private byte[] compressContent(String content) { - try{ - ByteArrayOutputStream baostream = new ByteArrayOutputStream(); - OutputStream outStream = new GZIPOutputStream(baostream); - outStream.write(content.getBytes("UTF-8")); + try (ByteArrayOutputStream baostream = new ByteArrayOutputStream(); + OutputStream outStream = new GZIPOutputStream(baostream)){ + outStream.write(content.getBytes()); outStream.close(); - byte[] compressedBytes = baostream.toByteArray(); // toString not always possible - return compressedBytes; + return baostream.toByteArray(); } catch (IOException e) { throw new RuntimeException("exception happened while compressing email content"); - } } diff --git a/src/test/java/com/designpatterns/decorator/DecoratorDemo.java b/src/test/java/com/designpatterns/decorator/DecoratorDemo.java index 08aaf02b0f7c..d28f3f68ed38 100644 --- a/src/test/java/com/designpatterns/decorator/DecoratorDemo.java +++ b/src/test/java/com/designpatterns/decorator/DecoratorDemo.java @@ -1,9 +1,6 @@ package com.designpatterns.decorator; -import com.designpatterns.structural.decorator.EmailSender; -import com.designpatterns.structural.decorator.EncodingDecorator; -import com.designpatterns.structural.decorator.Sender; -import com.designpatterns.structural.decorator.SenderDecorator; +import com.designpatterns.structural.decorator.*; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -16,28 +13,50 @@ public void testDecorator_sendEmailAsPlainText() { String message = "test message"; EmailSender sender = new EmailSender(); String content = sender.send(message); - Assertions.assertEquals(content, message); - } @Test - public void testDecorator_sendEmailAsEncodedTest() { + public void testDecorator_sendEmailAsEncodedText() { String message = "test message"; Sender sender = new SenderDecorator( new EncodingDecorator( new EmailSender() ) ); - String encodedContent = sender.send(message); - Assertions.assertEquals( new String(Base64.getDecoder().decode (encodedContent)), message ); + } + @Test + public void testDecorator_sendEmailAsCompressedText() { + String message = "Java is a general-purpose programming language that is class-based, object-oriented, and designed to have as few implementation dependencies as possible. It is intended to let application developers write once, run anywhere (WORA),[15] meaning that compiled Java code can run on all platforms that support Java without the need for recompilation.[16] Java applications are typically compiled to bytecode that can run on any Java virtual machine (JVM) regardless of the underlying computer architecture. The syntax of Java is similar to C and C++, but it has fewer low-level facilities than either of them. As of 2019, Java was one of the most popular programming languages in use according to GitHub,[17][18] particularly for client-server web applications, with a reported 9 million developers."; + Sender sender = new SenderDecorator( + new CompressingDecorator( + new EmailSender() + ) + ); + String compressedContent = sender.send(message); + Assertions.assertTrue(message.length()>= compressedContent.length()); + } + + @Test + public void testDecorator_sendEmailAsEncodedCompressedText() { + String message = "Java is a general-purpose programming language that is class-based, object-oriented, and designed to have as few implementation dependencies as possible. It is intended to let application developers write once, run anywhere (WORA),[15] meaning that compiled Java code can run on all platforms that support Java without the need for recompilation.[16] Java applications are typically compiled to bytecode that can run on any Java virtual machine (JVM) regardless of the underlying computer architecture. The syntax of Java is similar to C and C++, but it has fewer low-level facilities than either of them. As of 2019, Java was one of the most popular programming languages in use according to GitHub,[17][18] particularly for client-server web applications, with a reported 9 million developers."; + Sender sender = new SenderDecorator( + new EncodingDecorator( + new CompressingDecorator( + new EmailSender() + ) + ) + ); + String encodedCompressedContent = sender.send(message); + String decodedCompressed = new String( Base64.getDecoder().decode (encodedCompressedContent)); + Assertions.assertTrue(message.length()>= decodedCompressed.length()); } }