객체들을 새로운 행동을 포함한 특수 래퍼 객체 내에 넣어서 위 행동들을 해당 객체에 연결시키는 패턴
// Component 인터페이스
interface DataSource {
void writeData(String data);
String readData();
}
// Concrete Component 클래스
class FileDataSource implements DataSource {
private String filename;
public FileDataSource(String filename) {
this.filename = filename;
}
@Override
public void writeData(String data) {
System.out.println("Writing data to file: " + filename);
}
@Override
public String readData() {
System.out.println("Reading data from file: " + filename);
return "File data";
}
}
// Base Decorator 클래스
class DataSourceDecorator implements DataSource {
protected DataSource wrappee;
public DataSourceDecorator(DataSource source) {
this.wrappee = source;
}
@Override
public void writeData(String data) {
wrappee.writeData(data);
}
@Override
public String readData() {
return wrappee.readData();
}
}
// Concrete Decorator - Encryption
class EncryptionDecorator extends DataSourceDecorator {
public EncryptionDecorator(DataSource source) {
super(source);
}
@Override
public void writeData(String data) {
String encryptedData = encrypt(data);
System.out.println("Encrypting data.");
super.writeData(encryptedData);
}
@Override
public String readData() {
String data = super.readData();
String decryptedData = decrypt(data);
System.out.println("Decrypting data.");
return decryptedData;
}
private String encrypt(String data) {
return "Encrypted(" + data + ")";
}
private String decrypt(String data) {
return data.replace("Encrypted(", "").replace(")", "");
}
}
// Concrete Decorator - Compression
class CompressionDecorator extends DataSourceDecorator {
public CompressionDecorator(DataSource source) {
super(source);
}
@Override
public void writeData(String data) {
String compressedData = compress(data);
System.out.println("Compressing data.");
super.writeData(compressedData);
}
@Override
public String readData() {
String data = super.readData();
String decompressedData = decompress(data);
System.out.println("Decompressing data.");
return decompressedData;
}
private String compress(String data) {
return "Compressed(" + data + ")";
}
private String decompress(String data) {
return data.replace("Compressed(", "").replace(")", "");
}
}
// Client 코드
class Application {
public static void main(String[] args) {
DataSource source = new FileDataSource("somefile.dat");
// Compression 추가
source = new CompressionDecorator(source);
// Encryption 추가
source = new EncryptionDecorator(source);
// 데이터 쓰기
source.writeData("Salary Records");
// 데이터 읽기
String result = source.readData();
System.out.println("Final Data: " + result);
}
}
장점