Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Jndi DataSource
- 상호 인증
- Request Body 여러 번 사용
- Reading HttpServletRequest Multiple Times
- mapstruct
- Graphql Client
- Srping MVC
- 데이터 압축
- Unchecked Exception
- HandlerMethodArgumentResolver
- Tomcat DBCP
- NoUniqueBeanDefinitionException
- Java Singleton
- Java Rest
- Open Close Principal
- 바이트 절삭
- 이중정렬
- WildFly
- tomcat jndi
- 개방 폐쇄 원칙
- Socket is closed
- Checked Exception
- Sub Bytes
- java
- requestheaderdto
- AfterMapping
- graphql
- Java Graphql
- mTLS
- try - with - resources
Archives
- Today
- Total
Developer Sang Guy
OCP (Open Close Principal) 개방 폐쇄 원칙 본문
OCP - 개방 폐쇄 원칙
소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다
말로 설명하기는 어려우니 바로 소스를 보면서 얘기해보자
아래 소스는 OCP를 지키지 못한 상황이다.
User 객체
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
31
32
|
import java.util.Map;
public class User {
private String name;
private Map<String, Integer> pocket;
public User(String name, Map<String, Integer> pocket) {
this.name = name;
this.pocket = pocket;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<String, Integer> getPocket() {
return pocket;
}
public void setPocket(Map<String, Integer> pocket) {
this.pocket = pocket;
}
@Override
public String toString() {
return "name : " + name + ", pocket : " + pocket.toString();
}
}
|
cs |
거래를 담당 할 Trade 객체
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class Trade {
private BitCoin bitCoin = new BitCoin();
public User buyBitCoin(User user, String coinName, Integer quantity) {
return bitCoin.buy(user, coinName, quantity);
}
public User sellBitCoin(User user, String coinName, Integer quantity) {
return bitCoin.sell(user, coinName, quantity);
}
}
|
cs |
BitCoin 객체
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import java.util.Map;
public class BitCoin {
public User buy(User user, String coinName, Integer quantity) {
Map<String, Integer> pocket = user.getPocket();
pocket.put(coinName, quantity);
return new User(user.getName(), pocket);
}
public User sell(User user, String coinName, Integer quantity) {
Map<String, Integer> pocket = user.getPocket();
pocket.put(coinName, pocket.get(coinName) - quantity);
return new User(user.getName(), pocket);
}
}
|
cs |
위와 같은 상황에서 BitCoin 외 다른 코인을 거래하게 될 경우 아래와 같이 Trade 객체의 수정이 불가피하다.
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
|
public class Trade {
private BitCoin bitCoin = new BitCoin();
private dogeCoin dogeCoin = new dogeCoin();
public User buyBitCoin(User user, String coinName, Integer quantity) {
return bitCoin.buy(user, coinName, quantity);
}
public User sellBitCoin(User user, String coinName, Integer quantity) {
return bitCoin.sell(user, coinName, quantity);
}
public User buyDogeCoin(User user, String coinName, Integer quantity) {
return dogeCoin.buy(user, coinName, quantity);
}
public User sellDogeCoin(User user, String coinName, Integer quantity) {
return dogeCoin.sell(user, coinName, quantity);
}
}
|
cs |
DogeCoin이라는 코인을 추가(확장)하였지만 Trade 객체가 수정(변경)되어 위 소스는 OCP를 위반한 케이스다.
그러면 어떻게 Trade 객체의 수정없이 새로운 코인을 추가 할 수 있을까?
이 때 새로 추가 될 Coin에 대한 Interface의 등장으로 각 코인 객체들의 기능을 동일화하며 OCP 위반을 해소 할 수 있다.
새로 추가 된 Coin Interface
1
2
3
4
5
6
|
public interface Coin {
User buy(User user, String coinName, Integer quantity);
User sell(User user, String coinName, Integer quantity);
}
|
cs |
Coin Interface가 적용 된 BitCoin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import java.util.Map;
public class BitCoin implements Coin {
@Override
public User buy(User user, String coinName, Integer quantity) {
Map<String, Integer> pocket = user.getPocket();
pocket.put(coinName, quantity);
return new User(user.getName(), pocket);
}
@Override
public User sell(User user, String coinName, Integer quantity) {
Map<String, Integer> pocket = user.getPocket();
pocket.put(coinName, pocket.get(coinName) - quantity);
return new User(user.getName(), pocket);
}
}
|
cs |
Coin Interface가 적용 된 DogeCoin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import java.util.Map;
public class dogeCoin implements Coin {
@Override
public User buy(User user, String coinName, Integer quantity) {
Map<String, Integer> pocket = user.getPocket();
pocket.put(coinName, quantity);
return new User(user.getName(), pocket);
}
@Override
public User sell(User user, String coinName, Integer quantity) {
Map<String, Integer> pocket = user.getPocket();
pocket.put(coinName, pocket.get(coinName) - quantity);
return new User(user.getName(), pocket);
}
}
|
cs |
변경 된 Trade 객체
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class Trade {
private Coin coin;
public Trade(Coin coin) {
this.coin = coin;
}
public User buyCoin(User user, String coinName, Integer quantity) {
return coin.buy(user, coinName, quantity);
}
public User sellCoin(User user, String coinName, Integer quantity) {
return coin.sell(user, coinName, quantity);
}
}
|
cs |
위와 같이 변경 된 Trade 객체는 Coin Interface가 적용 된 코인이라면 모두 Buy, Sell 기능을 수행 할 수 있다.
Main
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
|
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
User user = new User("UserA", new HashMap<String, Integer>());
/* BitCoin 거래 */
Trade tradeBit = new Trade(new BitCoin());
tradeBit.buyCoin(user, "BitCoin", 155);
System.out.println(user.toString());
tradeBit.sellCoin(user, "BitCoin", 20);
System.out.println(user.toString());
/* DogeCoin 거래 */
Trade tradeDoge = new Trade(new dogeCoin());
tradeDoge.buyCoin(user, "DogeCoin", 547519);
System.out.println(user.toString());
tradeDoge.sellCoin(user, "DogeCoin", 5000);
System.out.println(user.toString());
}
}
|
cs |
결과 :
1
2
3
4
|
name : UserA, pocket : {BitCoin=155}
name : UserA, pocket : {BitCoin=135}
name : UserA, pocket : {BitCoin=135, DogeCoin=547519}
name : UserA, pocket : {BitCoin=135, DogeCoin=542519}
|
cs |
'Java' 카테고리의 다른 글
데이터 압축 (0) | 2022.05.26 |
---|---|
[Java]NonStaticInnerClass vs StaticInnerClass (0) | 2022.05.18 |
Java Graphql Client 구현 (0) | 2022.03.30 |
Java Http Rest 통신 소스 (0) | 2022.01.05 |
Java Singleton 객체 구현 및 주의 사항 (0) | 2021.05.16 |
Comments