JVM이란 무엇인가 Java Virtual Machine : 자바를 실행하기 위한 가상 컴퓨터 The Java™ Tutorials 자바로 작성된 애플리케이션은 이 가상 컴퓨터(JVM)위에서만 실행된다. 장점 Java application이 OS, 하드웨어에 독립적이기 때문에, OS와 하드웨어가 달라지더라도 Java application code를 변경할 필요가 없음 단점 JVM을 거쳐서 실행되기 때문에 속도가 느림. -> JIT 컴파일러와 최적화 기술로 속도 저하 문제를 해결. 컴파일 하는 방법 & 실행하는 방법 java 프로그램 작성 ( Main.java ) 컴파일 javac Main.java 결과 : Main.class 파일 생성 (bytecode, executable file) run java Ma..

상속을 이용해 기능을 확장한 예시를 들어보자. 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..

클래스는 단 한 개의 책임을 가져야 한다. 단일 책임 원칙이 지켜지지 않은 예 public class DataViewer{ public void display(){ String data = loadHtml(); updateGui(data); } public String loadHtml(){ HttpClient client = new HttpClient(); client.connect(url); return client.getResponse(); } private void updateGui(String data){ GuiData guiModel = parseDataToGuiData(data); tableUI.changeData(guiModel); } private GuidData parseDataToGui..
- Total
- Today
- Yesterday
- 토비의스프링
- 프록시
- AOP
- 프록시패턴
- provider
- 스프링
- 프로그래머스
- 메서드레퍼런스
- 카카오
- 토비의봄TV
- 김영한
- 데코레이터패턴
- 템플릿콜백
- 코딩테스트
- 자바
- 토비
- 백기선
- 서비스추상화
- 자바스터디
- 코테
- 예외처리
- gracefulshutdown
- java
- OOP
- ec2
- SOLID
- 디자인패턴
- 객체지향
- c++
- BOJ
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |