백엔드 웹개발 (Java/Spring) 초격차 - 2

김재현·2022년 9월 27일
0

FastCampus

목록 보기
2/9
post-thumbnail

객체 지향 패러다임

객체 지향의 4가지 특징

  • 객체 지향이 무엇인가? 에 대한 정답은 없을지라도, 객체지향이 무엇인가? 에 대한 자신의 답은 갖고 있어야한다.
  1. 추상화
    • 불필요한 부분을 제거함으로써 필요한 핵심적인 부분을 나타내는 것
    • 복잡성을 낮추기 위해 사용
  2. 다형성
    • 다양한 형태를 갖는 것.
    • 하나의 타입으로 여러 객체를 참조할 수 있다.
  3. 캡슐화
    • 객체 내부의 세부사항을 외부로부터 감추는 것.
    • 인터페이스만 공개함으로써 변경하기 쉬운 코드를 만드는 것.
  4. 상속
    • 부모로부터 물려받는 것.

객체 지향의 5가지 설계 원칙(SOLID)

  1. SRP : 단일 책임 원칙, Single Resptonsibility Principle
    • 하나의 코드는 하나의 기능과 권한, 책임을 가져야 함.
  2. OCP : 개방 폐쇄 원칙, Open/Closed Principle
    • 확장에는 열려있고 변경에는 닫혀 있어야 한다.
    • 기존 코드를 변경하지 않고 기능을 추가할 수 있어야한다.
  3. LSP : 리스코프 치환 원칙, Lisov`s Subsitution Principle
    • 상위 타입의 객체를 하위 타입의 객체로 치환해도 동작에 문제가 없어야한다.
  4. ISP : 인터페이스 분리 원칙, Interface Segregation Principle
    • 많은 기능을 갖은 인터페이스를 작은 단위로 분리시킴으로 클라이언트에게 필요한 인터페이스만 구현한다.
    • 클라이언트가 사용하지 않는 기능에 의존하게되면 예상하지 못한 문제가 발생할 수 있는데, 이를 예방할 수 있음.
  5. DIP : 의존성 역전의 원칙, Dependency Inversion Principle
    • 의존 관계를 맺을 때 자주 변경되는 쪽보다는 변경되지 않는 쪽에 의존하라.
    • 자기보다 변하기 쉬운 것에 의존하면 변화의 영향을 많이 받기에, 추상화된 인터페이스나 상위 클래스에 의존해야 한다.

객체지향 패러다임

  • 적절한 객체에게 적절한 책임을 할당, 서로 메시지를 주고 받으며 협력하도록 하는 것
  • 점점 증가하는 SW 복잡도를 낮추기 위해 객체지향 패러다임이 대두.
  • 중요 포인트 두가지
    • 클래스가 아닌 객체에 초점을 두자.
    • 객체들에게 얼마나 적절한 역할과 책임을 할당하는가?

절차지향 vs 객체지향

  • 책임이 한 곳에 집중돼 있는 방식(gtter) > 절차지향
    • 하나의 메서드에서 게터를 통해 값을 가져오고, 이것에 모든 처리가 집중된다면 절차지향.
  • 책임이 여러 객체로 적절히 분산 > 객체지향
    • 해당 책임을 가진 객체에게 메시지를 통해 협력하도록 구현하는 방식.

High cohesion, Loose coupling

  • 높은 응집도, 낮은 결합도.
    • 비슷한 것끼리는 모아둠. > 응집도를 높인다.
      다른 것끼리는 분리함.
    • 응집도가 높으면, 어떠한 변경이 생겼을 때 변경의 포인트가 하나로 집중될 수 있음. 한곳에 집중되어 있기 때문에 영향범위를 파악하는 것이 굉장히 쉽다.
    • 객체지향에 있어 변경 요구사항이 들어왔을 때, 특정 부분만 수정해도 된다는 것은 응집도가 높다는 것을 의미한다.
      어떠한 변경이 생겼을 때 변경이 다른 곳에 영향을 미치지 않는다면 그것은 낮은 결합도를 의미한다.
  • 객체지향 설계는 결국 유지보수와 관련된 중요한 개념.
    변경점이 생겼을 때 유연하게 대응할 수 있다.

설계 순서

  1. (설계에 앞서) 도메인을 구성하는 객체에는 어떤 것들이 있는지 고민
  2. 객체들 간의 관계 고민
  3. 동적인 객체를 정적인 타입으로 추상화, 도메인 모델링 하기
    • 객체들이 어떤 상태와 행동을 갖는지 결정이 되면, 공통적인 상태와 행동을 갖는 객체들을 타입으로 분류. 타입을 기반으로 클래스를 구현한다.
      클래스 : 공통적인 상태와 행동을 가지는 객체.
    • 복잡성을 낮출 수 있다.
  4. 협력 설계
    • 적절한 객체에 적절한 역할 할당
  5. 객체들을 포괄하는 타입에 적절한 책임 할당
    • 클래스에 적절한 책임 할당. 클라이어언트와 협력할 수 있는 public 인터페이스를 정의.
  6. 구현
    • 인터페이스 구현.
  • 참고 : 객체지향 세계에서는 모든 객체가 능동적인 존재여야한다.

사칙연산 계산기 만들기

  • 요구사항
    • 간단한 사칙연산
    • 양수로만 계산
    • 나눗셈에서 0으로 나눌 경우 IllegalArgument 예외 발생
    • MVC 패턴 (Model-View-Controller) 기반으로 구현

test code

  • add 부터

  • 피연산자 + 피연산자를 Calculator에게 전달하며 작업 위임.
    그 후 Calculator는 이에 대한 결과값을 전달해주는 형태로 구현하자.
  • Calculator에게 해당 규약을 갖는 public 인터페이스를 만들어준다.

  • 클래스와 메서드 생성
  • 퍼블릭 인터페이스를 생성했다.
    리턴값은 int이니 int로 설정

  • 일단 테스트 코드를 작성하자. 두 개의 피연산자가 필요하고, 하나의 연산자가 필요하며, 답이 반환된다.
    리턴값은 int.
  • 하지만 당연히 실패한다. 테스트 코드가 실패했다면, 성공시켜보자.

  • 인터페이스를 수정해준다. 이것으로 일단 테스트코드는 성공시킬 수 있다.
  • 테스트 코드가 성공했으니 심리적 안정감을 얻을 수 있고, 안심하고 리팩토링 할 수 있다.

  • +operator인 경우에 해당하는 코드를 짜넣었다. 테스트코드가 성공하였으니, 리팩토링이 잘 되었다고 생각할 수 있다.

  • -인 경우의 테스트코드. 하지만 -연산에 관한 부분이 없기 때문에 당연히 실패한다.

  • 뺄셈에 대한 코드를 짜넣었고 테스트코드도 성공한다.
  • 이런 사칙연산에 대한 테스트코드를 일일이 작성하지 않고 한번에 작성하는 방법은 없을까?

  • @ParameterizedTest로 할 수 있다.
  • 메서드 인자를 설정할 수 있다.
    int operand1, String operator, int operand2, int result
    메서드 인자들이 순환하며 메서드에 들어가 결과를 확인한다.
  • formulaAndResult은 static 이어야 한다.

  • calculate도 다 작성해준다.

  • 작성한 Calculator 클래스가 마음에 들지 않으니 리팩토링 해주자.
  • enum을 새로 만들어준다.
  • enum 마다 각각의 연산을 수행하고 싶다! > 추상메서드를 선언해주자.

  • 추상메서드에 대한 오버라이드 메서드를 구현체로 선언해줄 수 있다.

  • 다 한 모습. 리턴에 연산도 추가해준다.

  • Calculator는 굳이 자신이 계산을 모두 수행하는 것이 아닌, 인자를 ArithmeticOperator에 전달하고 작업을 위임하고 int값을 리턴받게 할 수 있다.
  • calculate 메서드를 생성해준다.

  • 추상메서드는 enum 각각에서 오버라이드를 함.
    calculate가 외부에 노출되는 퍼블릭 인터페이스

  • Calculator는 작업 요청을 받으면 ArithmeticOperator에 작업을 위임.
    ArithmeticOperator에서 연산자와 일치하는 enum 값을 가지고 오고 그 enum 값에 해당하는 메서드 중 하나를 실행함.
    결과값을 int로 리턴해준다.
  • 테스트 코드도 정상적으로 실행된다. 리팩토링이 잘 되었다는 것을 알 수 있다.
  • 이 작업으로 얻는 효과.
    1) 테스트코드를 성공시키면, 리팩토링할 때 안정감을 얻을 수 있다.
    2) 테스트코드에서 calculate에게 작업 위임(메시지 전달).
    객체지향답게 ArithmeticOperator라는 enum을 만들어 해당 enum에게 작업 위임.
    그럼 최종적으로 enum이 작업을 처리하고 결과값을 다시 전달해줌.
  • 객체들끼리 메시지를 주고받으며 협력해서 결과값을 전달하는 구조를 만들었다.

0개의 댓글