νμ¬ λ€λκ³ μλ νμ¬λ μ€ - ν κ΅¬μ‘°λ‘ λλμ΄ μλ€.
λλ μ νμ€ λ°±μλ μμ§λμ΄μΈλ°, κ²©μ£Όλ‘ μ νμ€ λ°±μλ νμλ₯Ό μ§ννλ€.
νμ¬ μν΄ μλ νμμ νλ‘ νΈμλ λΆλ€μ μ νμ€ νλ‘ νΈμλ κ°λ°μ λΆλ€λΌλ¦¬ ν
μ€νΈ κ΄λ ¨ μ€ν°λλ₯Ό νμ λ€κ³ νμ¬,
λ°±μλλ λ΄κ° νλ² μ€ν°λλ₯Ό μ μνλ©΄ μ΄λ¨κΉλ μκ°μ΄ λ€μλ€!
νμ λ, μ€ν°λ μ£Όμ μ μμμ λν΄μ μμ€λ₯Ό λμ‘κ³ , λ ν¬ν¨ 5λͺ
μ΄μ μ νμ€ λ°±μλ μ€ν°λλ₯Ό μ§ννκ² λμλ€.
νμ¬ ν & μ€ λ³λ‘ λ§μ΄ν¬λ‘ μλΉμ€λ₯Ό μ΄μ μ€μ΄λ―λ‘,
첫 μμμ λΉκ΅μ κ°κ²°νκ³ μ΅μν κ°λ
μΈ μ΄λ²€νΈ μμ± νμ©ν λ§μ΄ν¬λ‘ μλΉμ€ μν€ν
μ²μ λν μ£Όμ λ‘ μ§ννκ² λμλ€.
λ΄κ° μ§ννλ μ€ν°λλ§ λ κ±°μ 3κ°μΈλ°.. κ·Έλλ κ°μ΄ νλ©΄ λ€ μ’μ κ±°μ§~~γ
γ
μ΄ μ€ν°λλ₯Ό λΉ λ₯΄κ² λ§μΉκ³ , νμ¬ μμ€μ μ μ©ν λ§ν ν
μ€νΈ κ΄λ ¨ μ£Όμ λ μΈνλΌ μͺ½μΌλ‘ λμ΄κ°λ©΄ μ λ§ μ¬λ―Έμμ κ² κ°λ€!
μ€ν°λ μ€λΉλ₯Ό νλ©°, μ±
μ μ½μλλ° μ΄κ±Έ κ°μΈ λΈλ‘κ·Έμ κΈ°λ‘νλ©΄ μ΄λ¨κΉνμ¬ λ§€ Chapter λ₯Ό μ½μΌλ©° λ΄ κ²½νκ³Ό μκ°μ μ 리ν κ³ν!
첫 μ₯, λλ©μΈ μ£Όλ μ€κ³
μ·¨μ€, μ μ
λ μ λ§ λ§μ΄ 곡λΆνλ κ°λ
μΈλ°, μ΄μ μμΌ μ 리νλ€.
λͺ¨λΈμ΄λΌλ κ°λ
.
Grady Booch λ "λ¨μν ννν μ€μ μΈκ³" λΌκ³ λΆλ₯Έλ€κ³ νλ€.
λͺ¨λΈμ κ΄μ¬μ¬μ λΆλ¦¬κ° μ€μνλ€. λͺ¨λΈμ λ°λΌλ³΄λ κ΄μ¬μ¬μ λ°λΌ λͺ¨λΈμ μ μκ° λ¬λΌμ§κΈ°λ νλ€.
μ°λ¦¬λ κ°λ°μμ΄λ―λ‘, κΈ°νμλ λ§μΌν°λ± "μ
무 λ΄λΉμ" μ μμ μ λ κΉν μ΄ν΄νλ € λ
Έλ ₯νκ³ λͺ¨λΈμ μ€κ³ν΄μΌ νλ€.
μλΉμ€ λ μ΄μ΄ ν¨ν΄.
μ ν리μΌμ΄μ
μ΄ μ 곡νλ μ¬μ© κ°λ₯ν κΈ°λ₯ μ§ν©
λΉμ¦λμ€ λ‘μ§μ μΊ‘μν λ° ν΄λΌμκ² μν₯μ μ£Όμ§ μλ λ³νλ₯Ό μμ©νκ±°λ μ±λ₯ κ°μ μ νλμ κ°λ₯νκ² νλ€.
μ΄λ₯Ό ν
λ©΄, Restful API μ Socket μ΄λ grpc λ±μ νλ‘ν μ½μ μꡬνλ ν΄λΌμ΄μΈνΈλ₯Ό μΆ©μ‘±μν¬ μ μλ€.
λλ©μΈ λͺ¨λΈ ν¨ν΄.
μꡬμ¬νμ΄ λ€μν΄ μ§μ λ°λΌ, μ μ§λ³΄μμ±μ΄ μ΄λ €μμ§λ€.
λλ©μΈ λͺ¨λΈ μμ μ΄λ° λΉμ¦λμ€λ₯Ό λΆλ¦¬νλ€.
public class CartService {
public void addItem(String cartId, String ProductName, int quantity) {
int size = CartDao.selectItemSize(cartId);
if (size >= 10) {
throw RuntimeException("..");
}
}
}
// λ무λ μ λͺ
ν ν¨ν΄,, κ·Έλ¦¬κ³ μ€λλ§μ΄λ€ μλ° μ½λ,,
μ΄λ¬λ©΄ λ³κ²½ μμ²μ μ μ°νκ² λμ κ°λ₯νλ€. μ μ€μΌμ΄μ€μ λ³κ°λ‘~!
ν₯μ¬κ³ λ μν€ν
μ²
μλ μ λͺ
ν input, output adaptor μ usecase λ° domain & business logic κ·Έλ¦¬κ³ infra layer
μν°ν°
κ°λ°μλ λλ©μΈ κ°μ²΄λ³΄λ€ λ°μ΄ν°μ μ§μ€νλ κ²½ν₯μ΄ μλλ°, μ΄λ° κ²½ν₯μ±μ κ°μ§ κ°λ°μλ Entity λ₯Ό Table λ‘ κ°μ£Όνλ € νλ€.
ν
μ΄λΈκ³Ό κ΄κ³ μ€μ¬μ κ°μ§λ λ°μ΄ν° λͺ¨λΈμ λ¨Όμ λ§λ€κ³ , ν
μ΄λΈμ λμνλ ν΄λμ€λ‘ 맀ννλ©΄ Entity λ κ°μ₯ κΈ°λ³Έμ μΈ μ±
μμ κ°μ§ Information Holder μν μ κ°μ Έ getter, setter λ§ μ 곡νλ€.
Entity λ μλ³μκ° μ‘΄μ¬νλ©°, μμ μ£ΌκΈ°λ₯Ό κ°μ§λ€. μ΄λ₯Ό ν
λ©΄, id μ no λ±μ΄ μκ² λ€.
μ΄λ κ³ μ λ²νΈλ‘ UUID λ‘λ λ§μ΄ μ¬μ©νλ κ²½μ°κ° μλ€.
κ° κ°μ²΄
Entity μ λ€λ₯΄κ², μλ³μκ° νμ μλ κ°μ²΄μ΄λ€.
μ΄λ¦μ κ±Έλ§κ² Entity λ₯Ό μμνλ μμ±μ΄λΌ μκ°νλ©΄ νΈνλ€.
public class Product {
private String id;
private String no;
private String name;
private Volume volume;
}
public class Volume {
private int width;
private int height;
private int depth;
public Volume(int width, int height, int depth) {
this.width = width;
this.height = height;
this.depth = depth;
}
}
μ΄λ κ² μ μνλ©΄ μ΄λ¨κΉ? Volume μ κ° κ°μ²΄μ΄λ―λ‘ λΆλ³μ±μ λλ€. κ° νλλ₯Ό final λ‘ μ μΈνλ κ²μ κΈμ첨νμΌ κ²μ΄λ€.
λ§μ½ Product μ Volume μ΄ λ³κ²½ λλ μꡬμ¬νμ λμνλ €λ©΄ μλ‘μ΄(new) Volume μ λ£μ΄μ€μΌ νλ€.
κ° κ°μ²΄μλ λΉμ°ν λΉμ¦λμ€λ₯Ό μΊ‘μνκ° κ°λ₯νλ€. λμ±μλ‘~!
public class Volume {
private int width;
private int height;
private int depth;
public Volume(int width, int height, int depth) {
if(width * 1.5 >= depth) {
throw new RuntimeException("Nagative!");
}
this.width = width;
this.height = height;
this.depth = depth;
}
}
μ€μ© μ£Όμ~
μΈνλΌμ€νΈλμ² μλΉμ€
ν₯μ¬κ³ λ μμ μ μν μ΄λν°μ΄λ€.
DB, Network, API call, Mail sending, Event publishing λ±μ κΈ°μ μ μΈ μ
무λ₯Ό λ€λ£¬λ€.
μ΄ μ±
μμ λ€λ₯Έ μλΉμ€μ λΆλ¦¬νμ§ λͺ»νλ©΄ μμνκ³ κΉ¨λν λλ©μΈ λͺ¨λΈμ μΉ¨λ²νκ² λ κ²μ΄λ€. κ·Έλ‘ μΈν΄ λ
립μ μΈ ν
μ€νΈκ° λΆκ°λ₯!
μ ν리μΌμ΄μ
μλΉμ€
λ무λ μ λͺ
ν κ·Έ usecase.
νΈλμμ
κ΄λ¦¬, μΈνλΌμ€νΈλμ²μμ μνΈμμ©μ ν¬ν¨ν λΉμ¦λμ€ usecase μ νλ¦μ μ‘°μ νλ€.
μμ½νμλ©΄ ν΄λΌμ΄μΈνΈμ μμ²λΆν° μλ΅κΉμ§μ μΌλ ¨μ νΈλμμ
μ μ²λ¦¬νλ€.
λλ©μΈ κ°μ²΄μ μμΈλ₯Ό μ²λ¦¬νλ κ²λ νλμ μ±
μμ΄λ€.
logging, metrics, monitoring λ μ±
μμ΄λΌκ³ νλ€.
λλ©μΈ μλΉμ€
Eric Evans : Entity μ λΆμ¬νκΈ° μ ν©νμ§ μμ μ±
μμ κ°μ§λ κ°μ²΄.
λ§ κ·Έλλ‘ λλ©μΈμ μν κ°μ²΄μ΄λ―λ‘, μμ Pojo λ‘ κ΅¬νλμ΄μΌ νλ€.
μ΄λ₯Ό ν
λ©΄, Multi module μ core λͺ¨λμμ Spring μμ‘΄μ±μ΄ λΉ μ ΈμΌ νλ μ΄μ μ΄λ€.
μ€μν λΉμ¦λμ€ νλ‘μΈμ€λ₯Ό μννλ €κ±°λ,
μ΄λ€ μ»΄ν¬μ§μ
μμ λ€λ₯Έ μ»΄ν¬μ§μ
μΌλ‘ λλ©μΈ κ°μ²΄λ₯Ό λ³ννκ±°λ,
νλ μ΄μμ λλ©μΈ κ°μ²΄μμ μꡬνλ μ
λ ₯ κ°μ κ³μ°ν λ!
μΆκ°λ‘ λλ©μΈ μλΉμ€μ λͺ
μΉμ Service λ₯Ό ν¬ν¨ν기보λ€, λ¬Έμ μμμμ ν΄λμ€ μν μ λ λͺ
νν νννλ μ΄λ¦μ΄ λ«λ€.
public class ProductCreationPolicy {
public boolean isValid(Product product) {
// λΉμ¦λμ€ λ‘μ§
return true;
}
}
μ΄ μΈμλ, νμ
μ λ³ν, νΉμ λλ©μΈ κ°μ²΄λ₯Ό μ¬μ©νκ±°λ DTO λ‘ λ³ννκ±°λ λ°λμ κ²½μ°μΌ λ μ¬μ©νλ€.
μ 그리거νΈ
λλ©μΈ κ°μ²΄λ€μ μ°κ΄ κ΄κ³μμ λΆλ³μ(invariants)μ 보μ₯ν΄μΌ νλ λ¨μ
μ¬λ¬κ°μ Entity, VO λ‘ κ΅¬μ± λλ©° ν¬ν¨ν μ μλ€. Aggregate λ₯Ό λννλ Entity λ Aggregate Root λΌκ³ λ λΆλ₯Έλ€.
Aggregate λ μꡬμ¬νκ³Ό μ
무 μ§μμμ μκ°μ λ°λΌ λ¬λΌμ§λ κ°λ
μ΄λ―λ‘, λͺ
νν ν
μ€νΈμ μ μ μμ΄λ λͺ¨νΈν κ°λ
μ΄λΌκ³ λ λΆλ₯Έλ€.
μΌλ‘λ‘ Cart, Item, Product λΌλ Entity κ° μλλ°, Cart κ° Aggregate Root κ° λμμ λμ μμμ΄λ€.
public class Cart {
private String cartId;
private List<Item> items;
public Cart(String cartId) {
this.cartId = cartId;
this.items = new ArrayList<>();
}
public void addItem(Product product, int quantity) {
Item newItem = new Item(product, quantity);
this.items.add(newItem);
}
///
public boolean isEmpty() {
return this.items.isEmpty();
}
}
μ΄λ κ² Aggregate Root λ₯Ό μ μνκ³ , Usecase (application service) μμλ Aggregate λ₯Ό ν΅ν΄ μꡬμ¬νμ μννλ μΌλ ¨μ κ³Όμ λ§ λμ΄νλ©΄ λλ€.
μ΄λ κ² μ€κ³ν Aggregate λ λ¨μ ν
μ€νΈμλ ν¨μ¬ μ©μ΄νλ€. μ±
μμ΄ λΆλ¦¬ λμ΄ μκΈ° λλ¬Έ.
μ€κ³ κ·μΉμΌλ‘,
- λΉμ¦λμ€ λΆλ³μμ μ 그리거νΈλ‘ νμ
- μμ μ 그리거νΈλ‘ μ€κ³
- λ€λ₯Έ μ 그리거νΈλ μλ³μλ‘ μ°Έμ‘°
- μ 그리거νΈκ° λ³νλ κ²°κ³Όμ μΌκ΄μ±μ μ¬μ©
μΆμνλ ν΅μ¬
μμ λ§ν μ¬λ¬ κ°λ
μ μ€λ¬΄μ μ μ©νκΈ°λ νκ³κ° μλ€.
μ΄λ° λΉλ© λΈλ‘ μΈμ μ€μν κ² μ€ νλλ Abstract Core μ΄λ€.
Eric Evans λλ©μΈ μ£Όλ μ€κ³ μ μ μ€ μ΄λ° μ¬λ‘λ₯Ό μκ°νλ€.
1. μ λ°μμ μ°¨λμΌλ‘ μ§μ μ΄λ
2. μ λ°μμ μΌμ μ₯μ νΉμ μμΉλ‘ μ΄λ
3. μΌμ μ₯μ νΉμ μμΉμμ μΌμ μ₯μ λ€λ₯Έ μμΉλ‘ μ΄λ
4. μΌμ μ₯μ νΉμ μμΉμμ μ°¨λμΌλ‘ μ΄λ
Entity λ 컨ν
μ΄λ, μ λ°, μΌμ μ₯, μ°¨λ, ν¬λ μΈ λ±μ΄ μλ€.
μ΄λ»κ² μ€κ³ν κ²μΈκ°?
public inteface MovingService {
void move(Container container, Location from, Location to);
}
μ λ΅μ μλ€. νμ§λ§ λͺ¨λ Entity λ₯Ό ν¬ν¨νκΈ°λ³΄λ€ Usecase μμλ μ΄λ κ² κ°κ²°νκ² ννμ΄ κ°λ₯νλ€.
λͺ¨λΈλ§μ μ½κ² νλ©°, μ€νΌλ μ΄μ
λ λ¨μν΄μ‘λ€.
λλ©μΈ μ£Όλ μ€κ³, μ°Έ λ§μ΄ 곡λΆν κ°λ
μ΄λ€. κ°λ΅νμ§λ§ μ§μ μ 리νλ 건 μ²μμ΄λ€.
λ€μ μ±ν°λ κ°μ²΄μ§ν₯ μ€κ³ μμΉμΈλ°, μ΄κ±΄ μλ©΄μλ νμ μ μ©νκ³ , νΉν μ±
μ μλ κ°μ²΄λ‘ λΆλ¦¬ λ° μ€κ³κ° μ½μ§ μλ€.
λ€μ μ₯λ μ¬λ°κ² μ½μ΄λ³΄μ~!
μΆμ² : http://www.acornpub.co.kr/book/microservices-eventsourcing
κ·Έλ¦¬κ³ λ
μ΄λ²€νΈ μμ±κ³Ό λ§μ΄ν¬λ‘μλΉμ€ μν€ν μ²
μ΄λ²€νΈ μμ±μ μ΄ν΄νκΈ° μν΄ λλ©μΈ μ£Όλ μ€κ³μ κ°μ²΄μ§ν₯ μ€κ³ μμΉ(SOLID)μ μ°κ³ν΄μ μ€λͺ νλ μ± μ΄λ€.
www.acornpub.co.kr