브리지 패턴은 추상화와 구현을 분리하여 둘을 독립적으로 확장할 수 있도록 하는 디자인 패턴이다.
여러 모양과 색상이 있다고 가정해보자.
빨간색 원
파란색 사각형
모양과 색상을 조합하는 모든 경우를 각각 클래스로 정의하면 클래스의 수가 기하급수적으로 늘어난다.
브리지 패턴을 사용해서 모양과 색상을 분리하고 이들을 독립적으로 확장 할 수 있도록 해보자.
Shape 클래스는 추상화 역할을 한다.
// Shape 클래스: 추상화 역할
abstract class Shape {
protected Color color;
protected Shape(Color color) {
this.color = color;
}
public abstract void draw();
}
Color 인터페이스는 구현 역할을 한다.
// Color 인터페이스: 구현 역할
interface Color {
void applyColor();
}
Color 구현 클래스는 빨간색과 파란색을 구체적으로 구현한다.
// RedColor 클래스: 구체적인 구현
class RedColor implements Color {
@Override
public void applyColor() {
System.out.println("Applying red color.");
}
}
// BlueColor 클래스: 구체적인 구현
class BlueColor implements Color {
@Override
public void applyColor() {
System.out.println("Applying blue color.");
}
}
Shape 구현 클래스는 원과 사각형과 같은 모양이다.
// Circle 클래스: 구체적인 추상화
class Circle extends Shape {
public Circle(Color color) {
super(color);
}
@Override
public void draw() {
System.out.print("Drawing Circle. ");
color.applyColor();
}
}
// Square 클래스: 구체적인 추상화
class Square extends Shape {
public Square(Color color) {
super(color);
}
@Override
public void draw() {
System.out.print("Drawing Square. ");
color.applyColor();
}
}
이를 통해서 브리지 패턴을 사용하면 아래 코드와 같이 사용할 수 있다.
// 사용 예시
public class BridgePatternDemo {
public static void main(String[] args) {
Shape redCircle = new Circle(new RedColor());
Shape blueSquare = new Square(new BlueColor());
redCircle.draw(); // 출력: Drawing Circle. Applying red color.
blueSquare.draw(); // 출력: Drawing Square. Applying blue color.
}
}
형태를 나타내며 색상을 적용하는 추상 매서드 draw()를 정의한다.
Color는 applyColor()를 정의한다.
Cicle, Square는 구체적인 추상화 역할을 한다.
브리치 패턴을 사용하여 모양과 색상을 분리하여 독립적으로 확장 할 수 있다는것을 확인 할 수 있다.
실무에서는 어떤경우에 브리지 패턴을 사용할까?
예를 들어 리포트기능을 만들어야 한다고 생각해보자. 리포트는 PDF 파일 그리고 HTML파일로 포맷하는 기능이 필요하다.
리포트 포맷 인터페이스는 구현 역할을 한다.
// ReportFormat 인터페이스: 리포트 포맷의 공통 기능 정의
interface ReportFormat {
void generate(String content);
}
HTML 리포트와 PDF리포트에 대해 클래스를 만든다.
// HTMLReport 클래스: 구체적인 HTML 리포트 포맷
class HTMLReport implements ReportFormat {
@Override
public void generate(String content) {
System.out.println("Generating HTML report with content: " + content);
}
}
// PDFReport 클래스: 구체적인 PDF 리포트 포맷
class PDFReport implements ReportFormat {
@Override
public void generate(String content) {
System.out.println("Generating PDF report with content: " + content);
}
}
리포트의 공통 기능을 만든다. 이는 추상화 역할을 한다.
// Report 클래스: 리포트의 공통 기능 정의
abstract class Report {
protected ReportFormat format;
protected Report(ReportFormat format) {
this.format = format;
}
public abstract void createReport(String content);
}
구체적인 리포트 클래스를 만든다.
// SalesReport 클래스: 구체적인 리포트
class SalesReport extends Report {
public SalesReport(ReportFormat format) {
super(format);
}
@Override
public void createReport(String content) {
format.generate(content);
}
}
이렇게 만든 리포트 관련 소스코드를 어떻게 사용하는지는 아래 코드를 확인해보자
// 사용 예시
public class BridgePatternDemo {
public static void main(String[] args) {
ReportFormat htmlFormat = new HTMLReport();
ReportFormat pdfFormat = new PDFReport();
Report htmlSalesReport = new SalesReport(htmlFormat);
Report pdfSalesReport = new SalesReport(pdfFormat);
// HTML 포맷의 판매 보고서 생성
htmlSalesReport.createReport("Sales Data for 2023"); // 출력: Generating HTML report with content: Sales Data for 2023
// PDF 포맷의 판매 보고서 생성
pdfSalesReport.createReport("Sales Data for 2023"); // 출력: Generating PDF report with content: Sales Data for 2023
}
}
실제 현업에서 사용하는 소스코드는 아니지만 HTML과 PDF에 사용할 content의 format을 분리하여 각각 독립적으로 확장할 수 있는 베이스 코드를 확인했다.
'Design Pattern > 구조 패턴(Structural Patterns)' 카테고리의 다른 글
플라이웨이트(Flyweight) 패턴 - 구조 패턴 (Structural Patterns) (0) | 2024.05.23 |
---|---|
퍼사드(Facade) 패턴 - 구조 패턴 (Structural Patterns) (0) | 2024.05.23 |
데코레이터(Decorator) 패턴 - 구조 패턴 (Structural Patterns) (0) | 2024.05.23 |
컴포지트(Composite) 패턴 - 구조 패턴 (Structural Patterns) (0) | 2024.05.23 |
어댑터(Adapter) 패턴 - 구조 패턴 (Structural Patterns) (0) | 2024.05.16 |