Add all 23 GoF design pattern implementations (2026-06-13)
This commit is contained in:
53
02-structural/decorator/Main.java
Normal file
53
02-structural/decorator/Main.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package decorator;
|
||||
|
||||
/**
|
||||
* Decorator Design Pattern — Runnable Demo
|
||||
*
|
||||
* Shows how text processors can be stacked like Java IO streams.
|
||||
* Each decorator adds one behaviour; the order of wrapping matters.
|
||||
*
|
||||
* Run: javac decorator/*.java && java decorator.Main
|
||||
* Article: https://ankurm.com/decorator-design-pattern-java/
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== Decorator Design Pattern Demo ===\n");
|
||||
|
||||
String input = " hello world, badword is here ";
|
||||
System.out.println("Input: \"" + input + "\"");
|
||||
System.out.println();
|
||||
|
||||
// Stack 1: just trim
|
||||
TextProcessor trimOnly = new TrimDecorator(new PlainTextProcessor());
|
||||
System.out.println("Trim only: \"" + trimOnly.process(input) + "\"");
|
||||
|
||||
// Stack 2: trim, then upper case
|
||||
TextProcessor trimThenUpper =
|
||||
new UpperCaseDecorator(
|
||||
new TrimDecorator(
|
||||
new PlainTextProcessor()));
|
||||
System.out.println("Trim + UpperCase: \"" + trimThenUpper.process(input) + "\"");
|
||||
|
||||
// Stack 3: trim, filter profanity, then upper case
|
||||
TextProcessor full =
|
||||
new UpperCaseDecorator(
|
||||
new ProfanityFilterDecorator(
|
||||
new TrimDecorator(
|
||||
new PlainTextProcessor())));
|
||||
System.out.println("Trim + Filter + Upper: \"" + full.process(input) + "\"");
|
||||
|
||||
// Stack 4: different order — filter then trim (order matters!)
|
||||
TextProcessor filterFirst =
|
||||
new TrimDecorator(
|
||||
new ProfanityFilterDecorator(
|
||||
new PlainTextProcessor()));
|
||||
System.out.println("Filter + Trim: \"" + filterFirst.process(input) + "\"");
|
||||
|
||||
System.out.println();
|
||||
System.out.println("JDK parallel: new BufferedReader(new InputStreamReader(socket.getInputStream()))");
|
||||
System.out.println("Same pattern: each wrapper adds one behaviour, order matters.");
|
||||
|
||||
System.out.println("\n=== Demo complete ===");
|
||||
}
|
||||
}
|
||||
14
02-structural/decorator/PlainTextProcessor.java
Normal file
14
02-structural/decorator/PlainTextProcessor.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package decorator;
|
||||
|
||||
/**
|
||||
* Concrete Component — the base object being decorated.
|
||||
* Does nothing special: just returns the text as-is.
|
||||
* All decorators wrap this (or other decorators on top of it).
|
||||
*/
|
||||
public class PlainTextProcessor implements TextProcessor {
|
||||
|
||||
@Override
|
||||
public String process(String text) {
|
||||
return text; // base: no transformation
|
||||
}
|
||||
}
|
||||
20
02-structural/decorator/ProfanityFilterDecorator.java
Normal file
20
02-structural/decorator/ProfanityFilterDecorator.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package decorator;
|
||||
|
||||
/** Concrete Decorator 3: replaces bad words with asterisks. */
|
||||
public class ProfanityFilterDecorator extends TextDecorator {
|
||||
|
||||
private static final String[] BAD_WORDS = {"badword", "spam"};
|
||||
|
||||
public ProfanityFilterDecorator(TextProcessor wrapped) {
|
||||
super(wrapped);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String process(String text) {
|
||||
String result = super.process(text);
|
||||
for (String word : BAD_WORDS) {
|
||||
result = result.replaceAll("(?i)" + word, "*".repeat(word.length()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
25
02-structural/decorator/TextDecorator.java
Normal file
25
02-structural/decorator/TextDecorator.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package decorator;
|
||||
|
||||
/**
|
||||
* Base Decorator — holds a reference to the wrapped TextProcessor.
|
||||
* All concrete decorators extend this instead of implementing
|
||||
* TextProcessor directly. This avoids repeating the delegation
|
||||
* boilerplate in every decorator.
|
||||
*
|
||||
* Crucially: it delegates to the wrapped processor first,
|
||||
* then applies its own transformation to the result.
|
||||
*/
|
||||
public abstract class TextDecorator implements TextProcessor {
|
||||
|
||||
protected final TextProcessor wrapped;
|
||||
|
||||
protected TextDecorator(TextProcessor wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String process(String text) {
|
||||
// Delegate to the wrapped processor first, then let subclass apply its transform
|
||||
return wrapped.process(text);
|
||||
}
|
||||
}
|
||||
10
02-structural/decorator/TextProcessor.java
Normal file
10
02-structural/decorator/TextProcessor.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package decorator;
|
||||
|
||||
/**
|
||||
* Component interface — defines what all text processors do.
|
||||
* Both the concrete processor AND all decorators implement this.
|
||||
* This is what makes them stackable.
|
||||
*/
|
||||
public interface TextProcessor {
|
||||
String process(String text);
|
||||
}
|
||||
14
02-structural/decorator/TrimDecorator.java
Normal file
14
02-structural/decorator/TrimDecorator.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package decorator;
|
||||
|
||||
/** Concrete Decorator 2: trims leading/trailing whitespace. */
|
||||
public class TrimDecorator extends TextDecorator {
|
||||
|
||||
public TrimDecorator(TextProcessor wrapped) {
|
||||
super(wrapped);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String process(String text) {
|
||||
return super.process(text).trim();
|
||||
}
|
||||
}
|
||||
16
02-structural/decorator/UpperCaseDecorator.java
Normal file
16
02-structural/decorator/UpperCaseDecorator.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package decorator;
|
||||
|
||||
/** Concrete Decorator 1: converts all text to upper case. */
|
||||
public class UpperCaseDecorator extends TextDecorator {
|
||||
|
||||
public UpperCaseDecorator(TextProcessor wrapped) {
|
||||
super(wrapped);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String process(String text) {
|
||||
// Get the result from whatever is below us in the stack,
|
||||
// then apply OUR transformation on top of it.
|
||||
return super.process(text).toUpperCase();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user