์กฐ์ํธ๋์ ์ค๋ธ์ ํธ๋ฅผ ์ฝ๊ณ ์ ๋จธ๋ฆฟ์์ ์๋ ๋ด์ฉ๋ค์ ์ ๋ฆฌํ๋ฉฐ ์์ฑํ ๊ธ์ ๋๋ค.
๋ณ๊ฒฝ์ ์ทจ์ฝํ ์ฝ๋
public class Theater {
private TicketSeller ticketSeller;
public Theater(TicketSeller ticketSeller) {
this.ticketSeller = ticketSeller;
}
public void enter(Audience audience) {
// ๊ด๋๊ฐ ๊ฐ๋ฐฉ์ ์ด๋๊ถ์ด ์๋ค๋ฉด?
if (audience.getBag().hasInvitation()) {
Ticket ticket = ticketSeller.getTicketOffice().getTicket();
// ํฐ์ผ ์ ๊ณต
audience.getBag().setTicket(ticket);
// ์ด๋๊ถ์ด ์๋ค๋ฉด
} else {
Ticket ticket = ticketSeller.getTicketOffice().getTicket();
// ๊ด๋๊ฐ์ด ๊ฐ๊ณ ์๋ ํ๊ธ(amount)๋ฅผ ๋ฐ์ ํฐ์ผ ๊ตํ
audience.getBag().minusAmount(ticket.getFee());
ticketSeller.getTicketOffice().plusAmount(ticket.getFee());
audience.getBag().setTicket(ticket);
}
}
}
์ ์ฝ๋๋ ๊ด๋๊ฐ์ ๊ฐ๋ฐฉ์ ์ด๋์ฅ์ด ์์ผ๋ฉด ํฐ์ผ์ ๊ตํํ์ฌ ๊ด๋๊ฐ์๊ฒ ์ฃผ๊ณ , ์ด๋์ฅ์ด ์๋ค๋ฉด ๊ด๋๊ฐ์ ๊ฐ๋ฐฉ์์ ์๋ ํ๊ธ์ผ๋ก ํฐ์ผ์ ๊ตฌ๋งคํ ๋ค ํฐ์ผ์ ์ฃผ๋ ์ฝ๋์ด๋ค.
์ด ์ฝ๋์ ๋ฌธ์ ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
- ํฐ์ผ ํ๋งค์๊ณผ ๊ด๋๊ฐ๊ฐ์ ํ๋ ฅ๊ณผ์ ์ Theater๊ฐ ์ฃผ๋ํ๊ณ ๊ฐ์ํ๋ค.
- ๊ฐ์ฒด ๊ฐ ๊ฒฐํฉ๋๊ฐ ๋๋ฌด ๋์์ ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ํ๋ค๊ณ Audience๋ TicketSeller ์ ๋ณํ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ Theater ์ฝ๋๋ ์ํฅ์ ๋ฐ๋๋ค.
Audience๊ฐ Bag ํด๋์ค๊ฐ ์์ด์ง๋ค๋ฉด? ํ๊ธ(amount)์ด ์๋ ์ ์ฉ์นด๋ ๊ฒฐ์ ๋ ์ถ๊ฐ๋๋ค๋ฉด? ๋ฑ๋ฑ์ ๋ณํ๊ฐ ๋ฐ์ํ๋ฉด Theater ์ฝ๋๋ ์์ ํด์ฃผ์ด์ผ ํ๋ค.
๋ฐ๋ผ์, ๐ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ธฐ๋ฅ์ ๊ตฌํํ๋๋ฐ ํ์ํ ์ต์ํ์ ์์กด์ฑ๋ง ์ ์งํ๊ณ ๋ถํ์ํ ์์กด์ฑ์ ์ ๊ฑฐํ๋ ๊ฒ์ด ํ์ํ๋ค.
๊ทธ๋ฆฌ๊ณ ๐ก ์บก์ํ๊ฐ ํ์ํ๋ค.
Theater๋ Audience ๊ฐ์ฒด์ Bag ๊ฐ์ฒด์๋ ์ ๊ทผํ ์ ์์ผ๋ฉฐ TicketSeller์ TicketOffice์๋ ์ ๊ทผํ ์ ์๋ค.
์ด๋ฌํ ๋ถ๋ถ์ private ์ ์ด์๋ฅผ ํตํด ์์ ์ด ์์กดํ๋ ๊ฐ์ฒด๋ ์์ ์ด ์ฒ๋ฆฌํ ์ ์์ด์ผ ๊ฐ์ฒด๊ฐ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ ์ ์๋ค.
1๏ธโฃ ์บก์ํ๋ฅผ ํตํ ๊ฒฐํฉ๋ ๊ฐ์
public class Theater {
private TicketSeller ticketSeller;
public Theater(TicketSeller ticketSeller) {
this.ticketSeller = ticketSeller;
}
public void enter(Audience audience) {
ticketSeller.sellTo(audience);
}
}
๋ณ๊ฒฝ๋ ์ฝ๋๋ ์์ ๊ฐ๋ค.
Theater๋ ๊ด๋๊ฐ์ ๊ฐ๋ฐฉ์ ๋ฌด์์ด ์๋์ง, ์ด๋๊ถ์ ๊ตํํ๋์ง ๋ฑ๋ฑ์ ์ ๊ฒฝ์ฐ์ง ์๋๋ค.
ํ๋งค์์ด ๊ด๋๊ฐ์๊ฒ ์ด๋ ํ ํํ๋ก๋ ํฐ์ผ์ ํ๋งคํ์ผ๋ฉด ์ ์ฅ์์ผ์ฃผ๋ ์ญํ ๋ง ์ํํ๊ฒ ๋๋ค.
์ด์ ์ฝ๋์๋ Bag TicketOffice Ticket amount fee ๋ฑ ๋ค์ํ ๊ฐ์ฒด์ ๋ณ์์ ๊ฒฐํฉ๋์ด ์์์ง๋ง,
์์ ๋ ์ฝ๋์์๋ ๊ฒฐํฉ๋๊ฐ ๋ง์ด ๋ฎ์์ก์์ ํ๋์ ์ ์ ์๋ค.
public class TicketSeller {
private TicketOffice ticketOffice;
public TicketSeller(TicketOffice ticketOffice) {
this.ticketOffice = ticketOffice;
}
public void sellTo(Audience audience) {
if (audience.getBag().hasInvitation()) {
Ticket ticket = this.getTicketOffice().getTicket();
audience.getBag().setTicket(ticket);
} else {
Ticket ticket = this.getTicketOffice().getTicket();
audience.getBag().minusAmount(ticket.getFee());
this.getTicketOffice().plusAmount(ticket.getFee());
audience.getBag().setTicket(ticket);
}
}
}
ํฐ์ผ์ ํ๋งคํ๋ ์ญํ ์ ํ๋งค์๊ณผ ๊ด๋๊ฐ ์ฌ์ด์์ ์ด๋ฃจ์ด์ง๊ธฐ ๋๋ฌธ์
TicketSeller์์ ๋ฉ์๋๋ก์ ์ถ๊ฐํด์ฃผ๊ฒ ๋์๋ค.
๋ค๋ง, ์ ์ฝ๋ ์ญ์ TicketSeller๊ฐ Audience์ Bag์ ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ ํ๋ฒ๋ ์บก์ํ๋ฅผ ํตํด ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ ์ ์๋ค.
public class Audience {
private Bag bag;
public Audience(Bag bag) {
this.bag = bag;
}
public Long buy(Ticket ticket) {
if (bag.hasInvitation()) {
bag.setTicket(ticket);
return 0L;
} else {
bag.setTicket(ticket);
bag.minusAmount(ticket.getFee());
return ticket.getFee();
}
}
}
์ด์ ๊ด๋๊ฐ์ด ์ค์ค๋ก ์์ ์ Bag์ ๋ฉ์ธ์ง๋ฅผ ์ฃผ๊ณ ๋ฐ๊ณ ๊ด๋ฆฌํ๋ ์ฃผ์ฒด๊ฐ ๋์๋ค.
public class TicketSeller {
private TicketOffice ticketOffice;
public TicketSeller(TicketOffice ticketOffice) {
this.ticketOffice = ticketOffice;
}
public void sellTo(Audience audience) {
ticketOffice.plusAmount(audience.buy(ticketOffice.getTicket()));
}
}
๊ทธ๋ฆฌ๊ณ ํ๋งค์์ ๊ด๋๊ฐ์ด ์ด๋ค ๋ฐฉ์์ผ๋ก ํฐ์ผ์ ์๋์ง๋ ์ค์ํ์ง ์๊ณ ํฐ์ผ์ ๊ฑฐ๋ํ๊ณ ๋์์ ๊ฒฐ๊ณผ๋ฌผ ๋ง์ ์๊ฐํ๋ ์ฝ๋๋ก ๋ณ๊ฒฝ๋์๋ค.
TicketSeller๋ TicketOffice์ ํ๋์ธ Ticket์ ๋ง์๋๋ก ์ฌ์ฉํ๊ณ ์์ผ๋ฏ๋ก ์์ฒญํ๋ ๋ฐฉ์์ผ๋ก ๋ฐ๊ฟ๋ณด์.
public class TicketOffice {
private Long amount;
private List<Ticket> tickets = new ArrayList<>();
...
public void sellTicketTo(Audience audience) {
plusAmount(audience.buy(getTicket()));
}
}
TicketOffice๋ ์์ ์ ticket์ ์์ ์ด ์ฒ๋ฆฌํ๋ค.
๐จ ๋์ , TicketOffice๋ Audience๋ผ๋ ๊ฐ์ฒด๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ์์กดํ๊ฒ ๋๊ธด ํ๋ค.
public class TicketSeller {
private TicketOffice ticketOffice;
public TicketSeller(TicketOffice ticketOffice) {
this.ticketOffice = ticketOffice;
}
public void sellTo(Audience audience) {
ticketOffice.sellTicketTo(audience);
}
}
TicketSeller๋ TicketOffice์๊ฒ ํฐ์ผ์ ๊ด๋๊ฐ์๊ฒ ํ๊ฒ์ ์์ฒญํ๋ค.
์ด์ Audience๊ฐ Bag์ ๋ณ์๋ฅผ ๋ณ๊ฒฝํ์ง ๋ง๊ณ , Bag์๊ฒ ์์ฒญ์ ํ๋ ๋ฐฉ์์ผ๋ก ํ๋ฒ ๋ ๋ฆฌํฉํ ๋ง ํด๋ณด์.
public class Bag {
private Long amount;
private Invitation invitation;
private Ticket ticket;
public Bag(long amount) {
this(null, amount);
}
public Bag(Invitation invitation, long amount) {
this.invitation = invitation;
this.amount = amount;
}
public Long hold(Ticket ticket) {
if (hasInvitation()) {
setTicket(ticket);
return 0L;
} else {
setTicket(ticket);
minusAmount(ticket.getFee());
return ticket.getFee();
}
}
private boolean hasInvitation() {
return invitation != null;
}
public boolean hasTicket() {
return ticket != null;
}
private void setTicket(Ticket ticket) {
this.ticket = ticket;
}
private void minusAmount(Long amount) {
this.amount -= amount;
}
private void plusAmount(Long amount) {
this.amount += amount;
}
}
์ด์ Bag์ด ์์ ์ ํ๋๋ ์์ ์ด ๊ด๋ฆฌํ๊ฒ๋ ๋์๋ค.
public class Audience {
private Bag bag;
public Audience(Bag bag) {
this.bag = bag;
}
public Long buy(Ticket ticket) {
return bag.hold(ticket);
}
}
๊ด๋๊ฐ์ Bag ๊ฐ์ฒด์๊ฒ ํฐ์ผ์ ๊ฐ๊ณ ์์ ๊ฒ์ ์์ฒญํ๋ ์ฝ๋๊ฐ ๋์๋ค.
๐ก ์ด์ ๊ด๋๊ฐ์ด ๊ฐ๋ฐฉ์์ ์ง๊ฐ์ผ๋ก ๋ฐ๋์๋ , ๋น๋๋ด์ง๋ก ๋ฐ๋์๋ TicketSeller๋ ์ ๊ฒฝ์ฐ์ง ์๋๋ค.
๊ฐ์ฒด ์์ ๊ณผ ๊น๊ฒ ๊ฒฐํฉ๋์ด ์๋ ๊ฐ์ฒด๋, ์ 3์ ๊ฐ์ฒด๊ฐ ์๋ ์ค์ค๋ก ์ฒ๋ฆฌํ๊ฒ๋ ์๊ฐํ๋ฉด ์์ ๊ฐ์ ๋ฆฌํฉํ ๋ง์ ํ ์ ์๋ค.
์ด์ ๊ฐ์ด ๋ฐ์ ํ๊ฒ ์ฐ๊ด๋์ด ์๋ ์์ ์ ์์ ์ด ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ๋ฅผ ์์ง๋๊ฐ ๋๋ค๊ณ ๋งํ๋ค.
์ฆ, ๊ฐ์ฒด๊ฐ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ณ ์์ง๋๋ฅผ ๋์ด๋ ๋ฐฉ์์ผ๋ก ๊ฐ์ ์ํจ ๊ฒ์ด๋ผ๊ณ ํ ์ ์๊ฒ ๋ค.
ํ๋์ ๊ฐ์ฒด๋ ํ๋์ ์ฑ ์์ ๊ฐ์ ธ์ผ ํ๋ค๋ SOLID์ SRP ์
๋ณํ์๋ ๋ซํ์๊ณ ํ์ฅ์๋ ์ด๋ ค์์ด์ผ ํ๋ค๋ OCP ๋ฒ์น์ ์งํค๊ฒ๋ ๊ฐ์ ํ๋ค๊ณ ์๊ฐ์ด๋ ๋ค.
๊ฐ์ฒด ์งํฅ์ ๋์ฒ์ ์ ์๋ค๊ณ ์๊ฐํ ์ ์๋ ์ ์ฐจ์ ํ๋ก๊ทธ๋๋ฐ์ ํ์ํ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์์กดํด์ผํ๋ค๋ ์ ์์ ๋ณํ์ ๋งค์ฐ ์ทจ์ฝํ๋ค๊ณ ๋ณผ ์ ์๋ค.
๋ฐ๋ฉด์, ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ๐ก ์บก์ํ๋ฅผ ์ด์ฉํด ๊ฐ์ฒด ๊ฐ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถค์ผ๋ก์ ๋ณํ์ ์ ์ฐํ๊ณ ์ํฅ๋ ฅ์ด ๋๊ฒ ์ ํ๋๋ ๊ฒ์ ๋ง์ ์ ์๊ฒ ๋์๋ค.
๐จ ๋ฆฌํฉํ ๋ง ํ๋ ๊ณผ์ ์์ ์์กด์ฑ์ด ์๋ ๊ฐ์ฒด๋ค ๊ฐ์ ๊ฒฐํฉ๋ ์๊ธด ๊ฒฝ์ฐ๊ฐ ์์๋๋ฐ, ๋ชจ๋ ๊ฐ์ฒด๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ๊ณ ์ด๋ค ๊ฒฐํฉ์ด ๋ ์ ์ฉํ์ง ํ๋จํด์ ๊ฒฐ์ ํ๋ ๊ฒ์ ๊ฐ๋ฐ์์ ๋ชซ์ด ๋๋ค.