프록시 주요 기능 두 가지 접근 제어 권한에 따른 접근 차단 캐싱 지연 로딩 부가 기능 추가 원래 서버가 제공하는 기능에 더해서 부가 기능을 수행 e.g. 요청 값이나 응답 값 변형 e.g. 실행 시간을 측정해서 로그를 추가한다. 프록시 패턴 vs 데코레이터 패턴 프록시를 사용하는 목적(의도)에 따라 구분. 프록시 패턴 접근 제어 데코레이터 패턴 부가 기능 추가 프록시 패턴 코드 예시 데이터를 cache 하는 프록시 예제 public interface Subject { String operation(); } public class RealSubject implements Subject{ @Override public String operation() { log.info("실제 객체 호출"); sleep(..
템플릿 메서드 패턴 설명 코드에 변하는 부분과 변하지 않는 부분이 있을 때, 변하지 않는 부분을 추상 클래스 내 메서드로 정의하고, 변하는 부분을 추상 클래스 내 abstract 메서드로 정의하여 자식 클래스에서 변하는 부분을 abstract 메서드를 override 하여 구현하는 패턴. 코드 예시 public abstract class AbstractTemplate { public void execute() { long startTime = System.currentTimeMillis(); //비즈니스 로직 실행 call(); //비즈니스 로직 종료 long endTime = System.currentTimeMillis(); long resultTime = endTime - startTime; log...
상속을 이용해 기능을 확장한 예시를 들어보자. FileOut은 데이터를 파일에 출력하는 기능을 제공한다. 그리고 BufferedOut과 ZipOut은 각각 버퍼 기능과 압축 기능을 추가 제공한다. 그런데 만약 버퍼 기능과 압축 기능을 함께 제공하고 싶다면 어떻게 해야 할까? 이렇게 하위 클래스를 추가해서 구현할 수 있다. 이 방법은 직관적이지만 추가할 수 있는 기능이 많아질 경우 클래스의 개수가 지나치게 많아질 수 있다는 문제가 있다. 이럴 때 사용할 수 있는 것이 바로 데코레이터 패턴이다. 데코레이터 패턴은 상속이 아닌 '위임' 방식으로 기능을 확장한다. 구조가 조금 복잡해보이니 코드를 통해 이해해 보자. public abstract class Decorator implements FileOut { p..
자판기에 들어가는 소프트웨어를 만든다고 상상하자. 자판기는 다음과 같이 동작한다. 동작 상태 실행 결과 동전을 넣는다 동전 없음 금액을 증가 제품 선택 가능 상태 동전을 넣는다 제품 선택 가능 금액을 증가 제품 선택 가능 상태 제품을 선택한다 동전 없음 아무 동작하지 않음 동전 없음 상태 유지 제품을 선택한다 제품 선택 가능 제품을 주고 잔액 감소 잔액 있으면 제품 선택 가능 잔액 없으면 동전 없음 상태 위 표를 토대로 다음과 같은 프로그램을 작성했다. public class VendingMachine{ public static enum State { NOCOIN, SELECTABLE } private State state = State.NOCOIN; public void insertCoin(int co..
동일한 절차를 따르되, 일부 과정만 다른 코드를 짜는 경우가 있다. 예를 들어 인증을 처리할 때, DB 데이터를 사용하는 경우와 LDAP을 사용하는 경우를 생각해보자. 1) DB 데이터를 이용한 인증 처리 public class DbAuthenticator{ public Auth authenticate(String id, String pw){ //사용자 정보로 인증 확인 User user = userDao.selectById(id); boolean auth = user.equalPassword(pw); //인증 실패 예외 처리 if(!auth) throw createException(); //인증 성공시, 인증 정보 제공 return new Auth(id, user.getName()); } private..
첫 번째 손님, 그리고 신선하지 않은 과일에 대해 할인을 적용하는 과일 가게를 생각해보자. public class Calculator{ public int calculate(boolean firstGuest, List items){ int sum = 0; for (Item item : items){ if(firstGuest) sum += (int)(item.getPrice()*0.9); else if(!item.isFresh()) sum += (int)(item.getPrice()*0.8); else sum += item.getPrice(); } return sum; } } 간단한 코드지만 만약 할인 정책이 계속해서 추가된다면 if-else 문이 늘어나고 calculate의 parameter도 증가해 코..
고수준 모듈은 저수준 모듈의 구현에 의존해서는 안 된다. 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야 한다. 고수준 모듈 : 의미 있는 단일 기능을 제공하는 모듈 저수준 모듈 : 고수준 모듈 기능을 구현하기 위해 필요한 하위 기능의 실제 구현 예를 들어 상품의 가격을 결정하는 정책을 살펴보자. 고수준 : 쿠폰을 적용해서 가격 할인을 받을 수 있다. 저수준 : 가격 할인을 %로 할 것인가, 고정된 금액으로 할 것인가 등등... 만약 고수준인 '가격계산모듈'이 저소준 모듈(쿠폰 구현)에 의존한다면 어떤 문제가 생길까? 쿠폰 구현이 추가되거나 변경될 때마다 가격계산모듈의 코드에도 변경사항이 생길 것이다. 이러면 기능변경에 따른 프로그램의 변경이 어려워진다. 저소준 모듈이 변경되더라도 고소준 모듈..
인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다. 바꿔 말하면, 클라이언트는 자신이 사용하는 메소드에만 의존해야 한다. 다음 예제를 살펴보자. 게시글과 관련한 UI들이 모두 ArticleService 인터페이스를 구현하고 있다. 겉으로 보기에는 아무런 문제가 없어 보이지만.. 예를 들어 게시글 목록 관련된 메소드가 추가된다고 생각해보자. 그러면 게시글 목록 UI와 관련이 없는 게시글 작성 UI, 게시글 삭제 UI 에도 해당 메소드를 추가로 구현해야 할 것이다. 이는 단일책임원칙(SRP)이 위배된 것과 마찬가지로 한 기능의 변화가 다른 기능에 영향을 주고 있으므로 피해야할 상황이다. 그럼 이 문제를 어떻게 해결할 수 있을까? 위와 같이 인터페이스를 분리하면 된다. 이제 각 인터페이..
상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다. 무슨 말인지 모르겠다. 예제 코드로 살펴보자. 리스코프가 잘 지켜지지 않은 사례 : 직사각형-정사각형 문제 public class Rectangle{ private int width; private int height; public void setWidth(int width){ this.width = width; } public void setHeight(int height){ this.height = height; } public int getWidth(){ return width; } public int getHeight(){ return height; } } public class Square..
확장에는 열려 있어야 하고, 변경에는 닫혀야 한다. 말이 좀 어려운데, 풀어보면 다음과 같다. 기능을 변경하거나 확장할 수 있으면서, 그 기능을 사용하는 코드는 수정하지 않는다. 기능을 변경하면서 그 기능을 사용하는 코드는 바꾸면 안된다..? 이것이 가능한 얘기일까? 예시를 하나 들어보자. public class FlowController { public void process(){ FileDataReader reader = new FileDataReader(); byte[] data = reader.read(); Encryptor encryptor = new Encryptor(); byte[] encryptedData = encryptor.encrypt(data); FileDataWriter write..
- Total
- Today
- Yesterday
- BOJ
- provider
- 김영한
- OOP
- 코테
- 프로그래머스
- 메서드레퍼런스
- gracefulshutdown
- 토비의봄TV
- 토비의스프링
- 자바
- 서비스추상화
- 코딩테스트
- 데코레이터패턴
- 객체지향
- 디자인패턴
- 예외처리
- AOP
- ec2
- 백기선
- java
- 카카오
- 프록시패턴
- 토비
- 프록시
- SOLID
- c++
- 자바스터디
- 스프링
- 템플릿콜백
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |