프로그래밍 패러다임

패러다임 

한 시대의 사회전체가 공유하는 이론이나 방법, 문제 의식등의 체계

 

프로그래밍 패러다임 

특정 시대의 어느 성숙한 개발자 공동체에 의해 수용된 프로그래밍 방법과 문제 해결 방법, 프로그래밍 스타일.

우리가 어떤 프로그래밍 패러다임을 사용하느냐에 따라 우리가 해결할 문제를 바라보는 방식과 프로그램을 작성하는 방법이 달라진다. 프로그래밍 언어마다 채택하는 프로그래밍 패러다임이 다르다.

 

패러다임 전환 

절차형 패러다임에서 객체지향 패러다임으로의 변화를 가리킨다.

 

프로그래밍 패러다임의 역할

개발자 공동체가 동일한 프로그래밍 스타일과 모델을 공유할 수 있게 함으로써 불필요한 부분에 대한 의견 충돌을 방지한다. 

또한 교육시킴으로써 동일한 규칙과 방법을 공유하는 개발자로 성장하도록 준비시킬 수 있다.

특정한 종류의 문제를 해결하는데 필요한 일련의 개념들을 지원한다.


소극장 애플리케이션의 문제 

의도 

Theater : 관람객을 입장

TickerSeller : 티켓을 판매

Audience :  티켓 구매 

1. 예상을 빗나가는 코드 예시

내가 관람객이라고 가정할때, 관람객의 입장에서 소극장이라는 제3자가 초대장을 확인하기 위해 관람객의 가방을 마음대로 열어본다.

의도 : 티켓을 구매하는 관람객이 가방 안에서 돈을 직접 꺼내 판매원에게 지불한다.

2. 변경에 취약한 코드 예시

의존성 문제. 어떤 객체가 변경될 때 그 객체에게 의존하는 다른 객체로 함께 변경될 수 있다.

Theater가 Audience와 TicketSeller의 상세한 내부 구현까지 알고 있어야 한다.


설계 개선

// 문제코드
public class Theater{
	private TicketSeller ticketSeller;
    
    public Theater(TicketSeller ticketseller){
    this.ticketSeller = ticketSelelr;
    }
    
    public void enter(Audience audience){
        if(audience.getBag().hasInvitation()){ //TicketSeller의 sellTo()메소드로 옮긴다. TicketSeller의 내부구현을 캡슐화
            Ticket ticket = ticketSeller.getTicketOffice().getTicket();
            audience.getBag().setTicket(ticket);
        }else{
            Ticket ticket = ticketSeller.getTicketOffice().getTicket();
            audience.getBag().minusAmount(ticket.getFee());
            ticketSeller.getTicketOffice().plusAmount(ticket.getFee());
            audience.getBag().setTicket(ticket);
        }
	}
}
//개선 코드
public class Theater {
	private TicketSeller ticketSeller;
    
    public Theater(TicketSeller ticketSeller){
    	this.ticketSeller = ticketSeller;
        }
    
    public void enter(Audience audience){
    	ticketSeller.sellTo(audience); //TicketOffice에 접근하는 로직을 모두 ticketSeller.sellTo에 숨김
        }
    }

1. 자율성을 높이기

관람객과 판매원을 자율적인 존재로 만든다.

Theater가 TicketSeller와 Audience에 세세한 부분까지 알지 못하도록 정보를 차단한다.

관람객이 스스로 가방 안의 현금과 초대장을 처리하고 판매원이 스스로 매표소의 티켓과 판매 요금을 다루게 한다.

 

 

 

1.1 캡슐화 개념적이나 물리적으로 객체 내부의 세부적인 사항을 감추는 것.

객체 내부로의 접근을 제한해 객체와 객체 사이의 결합도를 낮춘다. -> 설계를 좀더 쉽게 변경 가능

접근 가능한 퍼블릭 메서드가 존재하지 않기때문에 외부에서 ticketOffice에 직접 접근할 수 없다. 오직 TicketSeller안에만 존재하게 된다. 

 

1.2 수정된 Theater class 어디서도 ticketOffice에 접근하지 않는다.

Theater 는 ticketOffice가 TicketSeller내부에 존재하는 사실을 모른다. 

Theater는 오직 TicketSeller 인터페이스에만 의존한다.

객체를 인터페이스와 구현으로 나누고 인터페이스만을 공개하는 것은 객체 사이의 결합도를 낮추고 변경하기 쉬운 코드를 작성한다. 

 

2. 자신의 문제해결

판매자가 티켓을 판매하기 위해 ticketOffice를 사용하는 모든 부분을 TicketSeller 내부로 옮기고, 관람객이 티켓을 구매하기 위해 Bag을 사용하는 모든 부분을 Audience 내부로 옮긴다. 

자신의 문제를 스스로 해결하도록 코드를 변경한다.


개선된 점

변경 용이성이 개선

TicketSeller의 내부 구현을 변경하더라도 Theater를 함께 변경할 필요가 없다. TicketSeller가 매표소가 아니라 은행에 돈을 보관하도록 만들고 싶으면 TicketSeller내부만 변경하면 된다.

 

책임의 이동

기존 코드는 책임이 Threater에 집중되어 있었다. 

독재자가 존재하지 않고, 각 객체에 책임이 적절하게 분배된다. 

데이터와 데이터를 사용하는 프로세스가 동일한 객체 안에 존재한다.  


절차지향

개선전의 Theater는 절차적 프로그래밍이다.

Theater enter메서드는 프로세스이며, Audience, TicketSeller, Bag, TicketOffice는 데이터이다. 

프로세스를 담당하는 Theater가  Audience, TicketSeller, Bag, TicketOffice 모두에 의존하고 있었다. 모든 처리가 하나의 클래스 안에 위치하고 나머지 클래스는 단지 데이터의 역할만 수행했다. 

프로세스와 데이터를 별도의 모듈에 위치시키는 방식이 절차지향이다.


객체지향 설계

  • 자신의 문제를 스스로 처리하기 때문에 예측이 가능하고, 이해하기 쉬우며 객체 내부의 변경이 객체 외부에 파급되지 않도록 제어할 수 있어서 변경하기가 수월하다.
  • 의존성 제거 : 불필요한 의존성을 제거-> 객체사이의 결합도를 낮추는 것
  • 캡슐화 : Theater가 몰라도 되는 세부사항을 Audience와 TicketSeller 내부로 감춰 캡슐화

좋은 설계

변경을 수용할 수 있어야한다.

요구사항은 항상 변경된다.  

오늘 요구하는 기능을 온전히 수행하면서 내일의 변경을 매끄럽게 수용할 수 있는 설계

 

 

'* > What I did today' 카테고리의 다른 글

@Jacksonized  (0) 2023.06.06
How to Achieve More  (3) 2023.03.14
DB Connection Pool  (0) 2023.02.15
Tree  (0) 2023.01.10
null 대신 Optional 클래스  (0) 2023.01.02
GC  (0) 2023.01.01
static 변수는 JVM의 어디에 저장될까 ?  (0) 2022.12.25
JVM  (0) 2022.12.24

+ Recent posts