A - Выкройка декоратора
A.1 - Пример использования шаблона Decorator
Шаблон Decorator используется для расширения устаревшей функциональности без изменения унаследованного класса. Допустим, у нас есть конкретный класс, который реализует интерфейс. И нам нужно расширить функциональность существующего метода, потому что существующий класс и его методы уже используются другими классами, поэтому мы не хотим вносить изменения в существующие классы. Но нам также нужны расширенные функциональные возможности для нового класса, тогда как нам решить эту проблему?
1- We can't change the existing legacy code
2- We want to extend the functionality
Поэтому мы используем шаблон декоратора, оборачивая существующий класс внутри декораторов.
B - Пример базового шаблона GoF Decorator
Здесь у нас есть простой интерфейс и класс реализации / бетона. Интерфейс имеет один простой метод, который является getMessageOfTheDay
и возвращает String
. Предположим, что есть много других классов, использующих этот метод. Поэтому, если мы хотим внести изменения в реализацию / конкретный класс, это повлияет на старый унаследованный код. Мы хотим изменить его только для новых классов, поэтому используем шаблон декоратора.
Вот тривиальный пример шаблона Gang Of Four Decorator Design;
B.1 - Greeter.java
public interface Greeter {
String getMessageOfTheDay();
}
B.2 - BasicGreeter.java
public class BasicGreeter implements Greeter {
@Override
public String getMessageOfTheDay() {
return "Welcome to my server";
}
}
B.3 - Класс абстрактного декоратора: GreeterDecorator.java
public abstract class GreeterDecorator implements Greeter {
protected Greeter greeter;
public GreeterDecorator(Greeter greeter) {
this.greeter = greeter;
}
public String getMessageOfTheDay() {
return greeter.getMessageOfTheDay();
}
}
B.4 - Класс бетонного декоратора: StrangerDecorator.java
public class StrangerDecorator extends GreeterDecorator {
public StrangerDecorator(Greeter greeter) {
super(greeter);
}
@Override
public String getMessageOfTheDay() {
return "Hello Stranger " + super.getMessageOfTheDay();
}
}
B.5 - демонстрационный код: DecoratorDemo .java
public class DecoratorDemo {
public static void main(String[] args) {
Greeter greeter = new BasicGreeter();
String motd = greeter.getMessageOfTheDay();
System.out.println(motd);
Greeter newGreeter = new StrangerDecorator(greeter);
String newMotd = newGreeter.getMessageOfTheDay();
System.out.println(newMotd);
Greeter muchNewGreeter = new StrangerDecorator(new StrangerDecorator(greeter));
String newestMotd = muchNewGreeter.getMessageOfTheDay();
System.out.println(newestMotd);
}
}
Посмотрите на эти примеры. Класс абстрактного декоратора необходим для переноса исходного контракта и реализации. Используя абстрактный декоратор, вы можете создать несколько новых декораторов, но в этом примере BasicGreeter обернут внутри абстрактного декоратора, и мы создали только новый класс декоратора, который является StrangeGreeter . Пожалуйста, сообщите, что классы декораторов могут использоваться как поезд, мы можем обернуть декоратор в другой декоратор или так же. Функциональность расширяема, но оригинальный класс сохраняется без каких-либо изменений.
C - Демонстрация OutputStream
Давайте посмотрим на этот пример. Мы хотим записать строку в файл с помощью OutputStream. Вот демонстрационный код;
C.1 - Пример демонстрации OutputStream для записи файла
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class FileWriterDemo {
public static void main(String[] args) throws IOException {
File file = new File("./normal.txt");
file.createNewFile();
OutputStream oStream = new FileOutputStream(file);
String content = "I love Commodore 64";
oStream.write(content.getBytes());
oStream.close();
}
}
C.2 - Вывод JSON-декоратора: normal.txt
В папке проекта будет создан новый файл с именем "normal.txt", содержимое которого будет;
I love Commodore 64
D - Демонстрационная демонстрация JSON OutputStream
Теперь я хочу создать формат оболочки JSON, который выглядит следующим образом;
{
data: <data here>
}
Я хочу написать содержимое в одном простом поле JSON в формате. Как мы можем достичь этой цели? Есть много тривиальных способов. Однако я буду использовать GoF Decorator Pattern , написав JSONDecorator , который расширяет класс OutputStream Java;
D.1 - JSON-декоратор для OutputStream: JSONStream.java
public class JSONStream extends OutputStream {
protected OutputStream outputStream;
public JSONStream(OutputStream outputStream) {
this.outputStream = outputStream;
}
@Override
public void write(int b) throws IOException {
outputStream.write(b);
}
@Override
public void write(byte[] b) throws IOException {
String content = new String(b);
content = "{\r\n\tdata:\"" + content + "\"\r\n}";
outputStream.write(content.getBytes());
}
}
D.2 - Демонстрация JSON Decorator: JSONDecoratorDemo.java
public class JSONDecoratorDemo {
public static void main(String[] args) throws IOException {
File file = new File("./json.txt");
file.createNewFile();
OutputStream oStream = new FileOutputStream(file);
JSONStream js = new JSONStream(oStream);
String content = "I love Commodore 64";
js.write(content.getBytes());
js.close();
oStream.close();
}
}
D.3 - Вывод JSON-декоратора: json.txt
{
data:"I love Commodore 64"
}
На самом деле, OutputStream сам является шаблоном декоратора, это абстрактный декоратор и конкретный декоратор, а вот класс JSONStream .