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..f1cea07b5437 --- /dev/null +++ b/src/main/java/com/designpatterns/structural/decorator/CompressingDecorator.java @@ -0,0 +1,37 @@ +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) { + 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()); + outStream.close(); + return baostream.toByteArray(); + } 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); + } +} 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..d28f3f68ed38 --- /dev/null +++ b/src/test/java/com/designpatterns/decorator/DecoratorDemo.java @@ -0,0 +1,62 @@ +package com.designpatterns.decorator; + +import com.designpatterns.structural.decorator.*; +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_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()); + } +}