[개요]
스프링이 사랑한 디자인 패턴1
1. Adapter Pattern(어댑터 패턴)
2. Proxy Pattern(프록시 패턴)
3. Decorator Pattern(데코레이터 패턴)
스프링이 사랑한 디자인 패턴2
1. Singleton Pattern(싱글턴 패턴)
2. Template Method Pattern(템플릿 메소드 패턴)
3. Factory Method Pattern(팩토리 메소드 패턴)
스프링이 사랑한 디자인 패턴3
1. Strategy Pattern(전략 패턴)
2. Template Callback Pattern(템플릿 콜백 패턴_견본/회신 패턴)
3. MVC 패턴
Strategy Pattern(전략 패턴)
-전략 패턴은 클라이언트가 전략을 생성해 전략을 실행할 컨텍스트에 주입하는 패턴입니다.
-전략 패턴은 디자인 패턴의 꽃이라고 할 정도로 다양한 곳에서 다양한 문제 상황의 해결책으로 사용됩니다.
-전략 패턴에는 개방 폐쇄 원칙(OCP)과 의존 역전 원칙(DIP)이 적용되었습니다.
-같은 문제의 해결책으로 상속을 이용하는 템플릿 메소드 패턴과 객체 주입을 통한 전략 패턴 중에서 선택/적용할 수 있습니다. 그런데 단일 상속만이 가능한 자바 언어에서는 상속이라는 제한이 있는 템플릿 메소드 패턴보다는 전략 패턴이 더 많이 사용됩니다.
전략 패턴을 구성하는 세 가지 요소
- 전략 메소드를 가진 전략 객체
- 전략 객체를 사용하는 컨텍스트(전략 객체의 사용자/소비자)
- 전략 객체를 생성해 컨텍스트에 주입하는 클라이언트(제 3자, 전략 객체의 공급자)
클라이언트는 다양한 전략 중 하나를 선택해 생성한 후 컨텍스트에 주입합니다.
//전략 인터페이스를 나타내는 Strategy.java
public interface Strategy {
public abstract void runStrategy();
}
//전략 인터페이스를 구현하는 StrategyGun.java
public class StrategyGun implements Strategy {
@Override
public void runStrategy() {
System.out.println("탕, 타당, 타다당");
}
}
무기 구현1: 총
//전략 인터페이스를 구현하는 StrategySword.java
public class StrategySword implements Strategy {
@Override
public void runStrategy() {
System.out.println("챙.. 채쟁챙 챙챙");
}
}
무기 구현2: 검
//전략 인터페이스를 구현하는 StrategyBow.java
public class StrategyBow implements Strategy {
@Override
public void runStrategy() {
System.out.println("슝.. 쐐액.. 쉑, 최종 병기");
}
}
무기 구현3: 활
//전략을 사용하는 컨텍스트 Soldier.java
public class Soldier {
void runContext(Strategy strategy) {
System.out.println("전투 시작");
strategy.runStrategy();
System.out.println("전투 종료");
}
}
무기(전략)를 사용할 군인(컨텍스트)
//전략 패턴의 클라이언트 Client.java
public class Client {
public static void main(String[] args) {
Strategy strategy=null;
Soldier rambo=new Soldier();
//총을 람보에게 전달해서 전투를 수행하게 합니다.
strategy=new StrategyGun();
rambo.runContext(strategy);
System.out.println();
//검을 람보에게 전달해서 전투를 수행하게 합니다.
strategy=new StrategySword();
rambo.runContext(strategy);
System.out.println();
//활을 람보에게 전달해서 전투를 수행하게 합니다.
strategy=new StrategyBow();
rambo.runContext(strategy);
}
}
무기(전략)를 조달(생성)해서 군인(컨텍스트)에게 지급(주입)해 줄 보급 장교(클라이언트, 제 3자)
위 코드의 실행 결과
->전투 시작
탕, 타당, 타다당
전투 종료
전투 시작
챙.. 채쟁챙 챙챙
전투 종료
전투 시작
슝.. 쐐액.. 쇅, 최종 병기
전투 종료
Template Callback Pattern(템플릿 콜백 패턴_견본/회신 패턴)
-템플릿 콜백 패턴은 전략 패턴의 변형으로, 스프링의 3대 프로그래밍 모델 중 하나인 DI(의존성 주입)에서 사용하는 특별한 형태의 전략 패턴입니다.
-템플릿 콜백 패턴은 전략 패턴과 모든 것이 동일한데, 전략을 익명 내부 클래스로 정의해서 사용한다는 특징이 있습니다.
-템플릿 콜백 패턴은 전략을 익명 내부 클래스로 구현한 전략 패턴입니다.
-템플릿 콜백 패턴도 전략 패턴과 마찬가지로 개방 폐쇄 원칙(OCP)과 의존 역전 원칙(DIP)이 적용된 설계 패턴입니다.
템플릿 콜백 패턴
//전략 인터페이스를 나타내는 Strategy.java
public interface Strategy {
public abstract void runStrategy();
}
//전략을 사용하는 컨텍스트 Soldier.java
public class Soldier {
void runContext(Strategy strategy) {
System.out.println("전투 시작");
strategy.runStrategy();
System.out.println("전투 종료");
}
}
//익명 내부 전략을 사용하는 클라이언트 Client.java
public class Client {
public static void main(String[] args) {
Soldier rambo=new Soldier();
rambo.runContext(new Strategy() {
@Override
public void runStrategy() {
System.out.println("총! 총초종총 총! 총!");
}
});
System.out.println();
rambo.runContext(new Strategy() {
@Override
public void runStrategy() {
System.out.println("칼! 카가갈 칼! 칼!");
}
});
System.out.println();
rambo.runContext(new Strategy() {
@Override
public void runStrategy() {
System.out.println("도끼! 독독..도도독 독끼!");
}
});
}
}
코드를 보면 많은 부분에서 중복된 코드가 보입니다. 이를 리팩토링해보겠습니다.
리팩토링한 템플릿 콜백 패턴
//Strategy.java
public interface Strategy {
public abstract void runStrategy();
}
//Soldier.java
public class Soldier {
void runContext(String weaponSound) {
System.out.println("전투 시작");
executeWeapon(weaponSound).runStrategy();
System.out.println("전투 종료");
}
private Strategy executeWeapon(final String weaponSound) {
return new Strategy() {
@Override
public void runStrategy() {
System.out.println(weaponSound);
}
};
}
}
전략 생성 코드가 컨텍스트(군인) 내부로 들어왔습니다.
//Client.java
public class Client {
public static void main(String[] args) {
Soldier rambo=new Soldier();
rambo.runContext("총! 총초종총 총! 총!");
System.out.println();
rambo.runContext("칼! 카가갈 칼! 칼!");
System.out.println();
rambo.runContext("도끼! 독독..도도독 독끼!");
}
}
MVC 패턴
-Model-View-Controller Pattern을 나타냅니다.
-MVC 패턴은 애플리케이션의 문제를 분리하는 데 사용됩니다.
- Model: 데이터를 전달하는 객체 또는 JAVA POJO를 나타냅니다. 또한 데이터가 변경되면 컨트롤러를 업데이트하는 로직을 가질 수 있습니다.
- View: 모델에 포함된 데이터의 시각화를 나타냅니다.
- Controller: 컨트롤러는 모델과 뷰 모두에서 작동하므로 모델의 컨트롤러와 뷰의 컨트롤러를 별도로 유지합니다. 모델 객체로의 데이터 흐름을 제어하고 데이터가 변경될 때마다 뷰를 업데이트합니다.
Student 개체를 만들어보겠습니다.
Model: Student
View: StudentView
Controller: StudentController
//Student.java
public class Student {
private String rollNo;
private String name;
public String getRollNo() {
return rollNo;
}
public void setRollNo(String rollNo) {
this.rollNo = rollNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
모델을 생성합니다.
//StudentView.java
public class StudentView {
public void printStudentDetails(String studentName, String studentRollNo){
System.out.println("Student: ");
System.out.println("Name: " + studentName);
System.out.println("Roll No: " + studentRollNo);
}
}
뷰를 생성합니다.
//StudentController.java
public class StudentController {
private Student model;
private StudentView view;
public StudentController(Student model, StudentView view){
this.model = model;
this.view = view;
}
public void setStudentName(String name){
model.setName(name);
}
public String getStudentName(){
return model.getName();
}
public void setStudentRollNo(String rollNo){
model.setRollNo(rollNo);
}
public String getStudentRollNo(){
return model.getRollNo();
}
public void updateView(){
view.printStudentDetails(model.getName(), model.getRollNo());
}
}
컨트롤러를 생성합니다.
//MVCPatternDemo.java
public class MVCPatternDemo {
public static void main(String[] args) {
//fetch student record based on his roll no from the database
Student model = retriveStudentFromDatabase();
//Create a view : to write student details on console
StudentView view = new StudentView();
StudentController controller = new StudentController(model, view);
controller.updateView();
//update model data
controller.setStudentName("John");
controller.updateView();
}
private static Student retriveStudentFromDatabase(){
Student student = new Student();
student.setName("Robert");
student.setRollNo("10");
return student;
}
}
StudentController 메소드를 사용하여 MVC 디자인 패턴의 사용을 보여줍니다.
위 코드의 실행 결과
->Student:
Name: Robert
Roll No: 10
Student:
Name: John
Roll No: 10
'Spring > additional' 카테고리의 다른 글
[디자인 패턴] Proxy Pattern(프록시 패턴) (0) | 2021.02.21 |
---|---|
[디자인 패턴] Adapter Pattern(어댑터 패턴) (0) | 2021.02.21 |
[Spring] 스프링이 사랑한 디자인 패턴2 (0) | 2021.02.21 |
[Spring] 스프링이 사랑한 디자인 패턴1 (0) | 2021.02.17 |
[Spring] Builder 패턴(Lombok 활용) (0) | 2021.02.14 |