: 기존 환경 내에서 반복적으로 일어나는 문제들을 어떻게 풀어나갈 것인가에 대한 일종의 솔루션
-
설계할 때 발생했던 문제점들을 객체 간의 상호관계 등을 이용하여 해결할 수 있도록 하나의 '규약' 형태로 만들어놓은 것
-
GoF의 디자인 패턴(디자인 패턴계의 교과서)에서는 객체지향적 디자인 패턴의 카테고리를 3가지로 분류
- 생성 패턴 (Creational Pattern)
- 구조 패턴 (Structural Pattern)
- 행동 패턴 (Behavioral Pattern)
: 객체의 생성에 관련된 패턴으로, 객체의 생성절차를 추상화하는 패턴
-
인스턴스를 만드는 절차를 추상화하는 패턴
-
시스템으로부터 객체의 생성/합성 방법을 분리해내기 위함
-
시스템이 어떤 구체 클래스를 사용하는지, 인스턴스들이 어떻게 만들어지고 어떻게 합성되는지에 대한 정보를 완전히 가려줌(캡슐화)
-
무엇
이 생성되나요? → 알 수 없음 -
어떻게
생성되나요? → 알 수 없음 -
언제
생성되나요? → 알 수 없음 -
누가
이걸 생성하나요? → 알 수 없음
: 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴
-
하나의 클래스를 기반으로 단 하나의 인스턴스를 만들어, 이를 기반으로 로직을 만드는 데에 쓰임
-
생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴함
-
하나의 인스턴스를 만들어놓고, 해당 인스턴스를 다른 모듈들이 공유하여 사용하기 때문에 인스턴스 생성 비용이 감소됨
-
모듈 간의 결합을 강하게 만든다는 단점이 있음
💡 이러한 모듈 간의 결합을 조금 느슨하게 하기 위해 의존성 주입(Dependency Injection)이라는 개념을 사용할 수 있다.
-
보통 데이터베이스 연결 모듈(DBCP, DataBase Connection Pool)에 많이 사용함 (DB 연결 과정이 부하가 크고, 한 번 연결된 객체를 계속 사용해야 하기 때문)
-
스프링 컨테이너도 객체를 싱글톤으로 관리함
Java에서의 싱글톤 구현
class Singleton {
private static class singleInstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return singleInstanceHolder.INSTANCE;
}
}
public class HelloWorld {
public static void main(String[] args) {
Singleton a = Singleton.getInstance();
Singleton b = Singleton.getInstance();
System.out.println(a.hashCode());
System.out.println(b.hashCode());
if (a == b) {
System.out.println(true);
}
}
}
JDBC에서 싱글톤을 활용하여 DB 연결하기
// 데이터베이스와 연결과 끊어주기위한 클래스
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBConn {
private static Connection dbConn;
public static Connection getConnection() throws SQLException, ClassNotFoundException{
if (dbConn == null){
//dbConn이 null이면, 연결된 것이 없으니 연결해야한다.
String url = "jdbc:oracle:thin:@127.0.0.1:1521:xe" ;
String user = "hr";
String pass = "12345";
Class. forName("oracle.jdbc.driver.OracleDriver");
dbConn = DriverManager.getConnection(url, user, pass);
}
return dbConn ;
}
//db와의 연결을 맺어주기 위한 메소드.
public static void close() throws SQLException {
if (dbConn != null){
if(!dbConn .isClosed()){
dbConn.close();
}
}
}
//db와의 연결을 끊어주는 메소드
}
// ex) 연결하기 예제
import java.sql.Connection;
public class jdbcTest {
public static void main(String[] args) {
try{
Connection conn = DBConn.getConnection ();
//정의한 DBConn 클래스로 손쉽게 연결.
System. out.println("오라클에 연결되었습니다." );
} catch(Exception e){
System. out.println(e.toString());
}
}
}
-
객체지향 프로그래밍의 핵심인 상속과 다형성을 해친다.
-
객체지향 프로그래밍의 또 다른 핵심인 정보 은닉을 해친다. 공유의 목적으로 생성된 클래스이기 때문에, 객체를 요청하는 메소드를 public으로 강제할 수밖에 없다.
-
Java의 고정적 싱글턴 패턴은 객체가 하나인 것을 보장할 수 없다.
💡 싱글턴 패턴을 사용할 땐 조심하자!
즉, 싱글턴 패턴은 굉장히 많이 활용되는 패턴이나, 앞서 말한 객체지향 프로그래밍의 기본 사상들을 많이 침해하기 때문에 굉장히 비판을 많이 받는 디자인 패턴이다.
따라서 싱글턴 패턴은 사용 시 매우 조심해서 사용해야 한다.
그것이 아니라면 위의 고전적인 싱글턴 패턴이 아닌 개선된 방식으로 객체의 싱글턴 방식을 구현하여 사용해야 한다.
: 객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패턴
-
상속 관계에 있는 두 클래스에서, 상위 클래스가 중요한 뼈대를 결정하고, 하위 클래스에서 객체 생성에 관한 구체적인 내용을 결정함
-
상위 클래스와 하위 클래스가 분리되기 때문에 느슨한 결합을 가짐
-
상위 클래스에서는 인스턴스 생성 방식에 대해 전혀 알 필요가 없기 때문에, 더 많은 유연성을 가지게 됨
-
객체 생성 로직이 따로 떼어져 있기 때문에, 코드를 리팩터링하더라도 한 곳만 고칠 수 있게 됨 → 유지 보수성 증가
-
팩토리 메소드 패턴 : 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 만든다. 즉 팩토리 메소드 패턴을 이용하면 클래스의 인스턴스를 만드는 일을 서브클래스에게 맡기는 것.
-
추상 팩토리 패턴 : 인터페이스를 이용하여 서로 연관된, 또는 의존하는 객체를 구상 클래스를 지정하지 않고도 생성.
Java에서의 팩토리 패턴 구현
추후 작성 예정
💡 Enum 타입
- 상수의 집합을 정의할 때 사용되는 타입
- 코드를 리팩터링할 때 해당 집합에 관한 로직 수정 시 이 부분만 수정하면 됨 : 큰 강점
: 대상 객체(subject)에 접근하기 전, 그 접근에 대한 흐름을 가로채 대상 객체 앞단의 인터페이스 역할을 하는 디자인 패턴
-
이를 통해 객체의 속성, 변환 등을 보안 / 데이터 검증 / 캐싱 / 로깅에 사용함
-
프록시 객체로 쓰이기도 하지만, 프록시 서버로도 활용함
: 어떠한 대상의 기본적인 동작(속성 접근, 할당, 순회, 열거, 함수 호출 등)의 작업을 가로챌 수 있는 객체를 뜻함
-
자바스크립트에서 프록시 객체는 2개의 매개변수를 가짐
-
프록시 패턴이 녹아들어 있는 객체
-
target
: 프록시할 대상 -
handler
: 프록시 객체의 target 동작을 가로채서 정의할 동작들이 정해져 있는 함수
: 서버와 클라이언트 사이에서 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용프로그램
-
nginx : 비동기 이벤트 기반의 구조와 다수의 연결을 효과적으로 처리 가능한 웹 서버. nginx를 프록시 서버로 둬서 실제 포트를 숨길 수도 있고, 정적 자원을 gzip 압축하거나, 메인 서버 앞단에서의 로딩을 할 수도 있다.
프록시 서버를 통해, 익명 사용자의 직접적인 서버로의 접근을 차단하고, 간접적으로 한 단계를 더 거침으로써 보안성을 더욱 강화할 수 있다.
: 객체의 행위를 바꾸고 싶은 경우 '직접' 수정하지 않고 전략이라고 부르는 '캡슐화한 알고리즘'을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴. = 정책 패턴(Policy Pattern)
💡 컨텍스트 프로그래밍에서의 컨텍스트 : 상황, 맥락, 문맥을 의미하며, 개발자가 어떠한 작업을 완료하는 데 필요한 모든 관련 정보
: 주체가 어떤 객체의 상태 변화를 관찰하다가 상태 변화가 있을 때마다 메서드 등을 통해 옵저버 목록에 있는 옵저버들에게 변화를 알려주는 디자인 패턴
- 주체 : 객체의 상태 변화를 보고 있는 관찰자
- 옵저버 : 이 객체의 상태 변화에 따라 전달되는 메서드 등을 기반으로 '추가 변화 사항'이 생기는 객체들
-
Twitter(트위터) : 주체가 포스팅을 올리게 되면 알림이 팔로워에게 감
-
Event-Driven System
-
MVC 패턴 : Model(=주체)에서 변경 사항이 생겨 update() 메서드로 View(=옵저버)에 알려주고, 이를 기반으로 Controller가 작동함