TDD & 객체지향/함수형 프로그래밍

Yiseul·2022년 1월 2일
0

조각지식

목록 보기
3/20

TDD 란?

Test-Driven Development(TDD)는 매우 짧은 개발 사이클의 반복에 의존하는 소프트웨어 개발 프로세스이다. 우선 개발자는 요구되는 새로운 기능에 대한 자동화된 테스트케이스를 작성하고 해당 테스트를 통과하는 가장 간단한 코드를 작성한다. 일단 테스트 통과하는 코드를 작성하고 상황에 맞게 리팩토링하는 과정을 거치는 것이다. 말 그대로 테스트가 코드 작성을 주도하는 개발방식인 것이다.

테스트 주도형 개발에선, 새로운 기능을 추가하기 전 테스트를 먼저 작성한다. 테스트를 작성하기 위해서, 개발자는 해당 기능의 요구사항과 명세를 분명히 이해하고 있어야 한다.
어떤 새로운 기능을 추가하면 잘 작동하던 기능이 제대로 작동하지 않는 경우가 발생할 수 있다.
새로운 기능을 추가할 때 테스트 코드를 작성함으로써, 새로운 기능이 제대로 작동함과 동시에 기존의 기능들이 잘 작동하는지 테스트를 통해 확인할 수 있는 것이다.

Refactor code
'좋은 코드'를 작성하기란 정말 쉽지가 않다. 코드를 작성할 때 고려해야 할 요소가 한 두 가지가 아니기 때문이다. 가독성이 좋게 coding convention 을 맞춰야 하며, 네이밍 규칙을 적용하여 메소드명, 변수명, 클래스명에 일관성을 줘야하며, 앞으로의 확장성 또한 고려해야 한다. 이와 동시에 비즈니스 로직에 대한 고려도 반드시 필요하며, 예외처리 부분 역시 빠뜨릴 수 없다.

코드량이 방대해지면서 리팩토링을 하게 된다. 이 때 테스트 주도 개발을 통해 개발을 해왔다면, 테스트 코드가 그 중심을 잡아줄 수 있다. 리팩토링 속도도 빨라지고 코드의 퀄리티도 그만큼 향상하게 되는 것이다. 보다 확장 가능이 용이한 코드, 재설계의 시간을 단축시킬 수 있는 코드, 디버깅 시간이 단축되는 코드가 TDD 와 함께 탄생하는 것이다.

코드를 작성하고나서 제대로 작동하는지 판단해야하는 시점이 온다. 물론 중간 중간 수동으로 확인도 할 것이다. 또 테스트에 대한 부분에 대한 문서도 만들어야 한다. 그 부분을 자동으로 해주면서, 코드 작성에 도움을 주는 것이 TDD 인 것이다.

TDD에 대해 생각해봐야 할 점
Q. 코드 생산성?
분명 코드량이 늘어난다. 비즈니스 로직, 각종 코드 디자인에도 시간이 많이 소요되는데, 거기에다가 테스트 코드까지 작성하기란 여간 벅찬 일이 아닐 것이다. 코드 퀄리티보다는 빠른 생산성이 요구되는 시점에서 TDD 는 큰 걸림돌이 될 수 있다.

Q. 모든 상황에 대해서 테스트 코드를 작성할 수 있는가? 작성해야 하는가?
세상에는 다양한 사용자가 존재하며, 생각지도 못한 예외 케이스가 존재할 수 있고 또 주객이 전도하는 상황이 발생할 수 있다. 분명 실제 코드가 더 중심이 되어야 하는데 테스트를 위해서 코드의 구조를 바꿔야 하는 고민이 생길 수도 있다.

모든 코드에 대해서 테스트 코드를 작성할 수 없으며 작성할 필요도 없다. 또한 테스트 코드를 작성한다고 해서 버그가 발생하지 않는 것도 아니다. 애초에 TDD 는 100% coverage 와 100% 무결성을 주장하지 않았다.

프로그래밍 패러다임
어느 하나가 다른 것을 대체할 수 있는 개념이 아니라 원하는 목표에 따라 적절히 결합하여 사용하는 것이 좋다.

Object Oriented Programming 객체지향프로그래밍

객체지향 프로그래밍이란 인간 중심적 프로그래밍 패러다임이라고 할 수 있다. 즉, 현실 세계를 프로그래밍으로 옮겨와 프로그래밍하는 것을 말한다.

OOP로 코드를 작성하면 이미 작성한 코드에 대한 재사용성이 높다. 자주 사용되는 로직을 라이브러리로 만들어두면 계속해서 사용할 수 있으며 그 신뢰성을 확보 할 수 있다. 또한 라이브러리를 각종 예외상황에 맞게 잘 만들어두면 개발자가 사소한 실수를 하더라도 그 에러를 컴파일 단계에서 잡아낼 수 있으므로 버그 발생이 줄어든다. 또한 내부적으로 어떻게 동작하는지 몰라도 개발자는 라이브러리가 제공하는 기능들을 사용할 수 있기 때문에 생산성이 높아지게 된다. 객체 단위로 코드가 나눠져 작성되기 때문에 디버깅이 쉽고 유지보수에 용이하다. 또한 데이터 모델링을 할 때 객체와 매핑하는 것이 수월하기 때문에 요구사항을 보다 명확하게 파악하여 프로그래밍 할 수 있다.

객체 지향 프로그래밍의 치명적인 단점은 함수형 프로그래밍 패러다임의 등장 배경을 통해서 알 수 있다. 바로 객체가 상태를 갖는다는 것이다. 변수가 존재하고 이 변수를 통해 객체가 예측할 수 없는 상태를 갖게 되어 애플리케이션 내부에서 버그를 발생시킨다는 것이다. 이러한 이유로 함수형 패러다임이 주목받고 있다.

  1. 추상화
    현실 세계의 사물들을 객체라고 보고 그 객체로부터 개발하고자 하는 애플리케이션에 필요한 특징들만을 뽑아와(간소화) 프로그래밍 하는 것을 추상화라고 한다. 자료의 추상화라고 할 수 있다.

  2. 캡슐화
    관련있는 멤버 변수와 메소드를 클래스와 같은 하나의 틀 안에 담고 외부에 공개될 필요가 없는 정보는 숨기는 것을 말하며 다른 말로 정보 은닉이라고 한다.
    캡슐화는 코드를 재수정없이 재활용할 수 있게 한다.
    실제 구현 내용 일부를 외부에 은닉 (접근 제어자 public/ protected/ private 로 정보은닉)

  3. 다향성
    하나의 변수명, 함수명 등이 상황에 따라 다른 의미로 해석될 수 있는 것이다.즉, 오버라이딩(Overriding), 오버로딩(Overloading)이 가능하다.
    오버라이딩 : 부모클래스의 메서드와 같은 이름, 매개변수를 재정의 하는 것.
    오버로딩 : 같은 이름의 함수를 여러 개 정의하고, 매개변수의 타입과 개수를 다르게 하여 매개변수에 따라 다르게 호출할 수 있게 하는 것.

  4. 상속
    상속은 부모클래스의 속성과 기능을 그대로 이어받아 사용할 수 있게하고 기능의 일부분을 변경해야 할 경우 상속받은 자식클래스에서 해당 기능만 다시 수정(정의)하여 사용할 수 있게 하는 것이다.

  5. 클래스와 객체
    클래스 : 추상화를 거쳐 집단에 속하는 속성과 행위를 변수와 메서드로 정의한 것
    인스턴스(객체) : 클래스에서 정의한 것을 토대로 실제 메모리상에 할당된 것으로 실제 프로그램에서 사용되는 데이터

  6. 동적바인딩
    실행 시 또는 컴파일 시에 발생할 때 변하지 않는 정적 연결과 대조되는 개념이다. 동적 연결은 프로그램 개체나 기호를 실행 프로세스의 여러 속성 또는 작업에 바인딩 한다. 다향성과 관련이 있다.

객체 지향적 설계 원칙
1. SRP(Single Responsibility Principle) : 단일 책임 원칙 클래스는 단 하나의 책임을 가져야 하며 클래스를 변경하는 이유는 단 하나의 이유이어야 한다.
2. OCP(Open-Closed Principle) : 개방-폐쇄 원칙 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다.
3. LSP(Liskov Substitution Principle) : 리스코프 치환 원칙 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
4. ISP(Interface Segregation Principle) : 인터페이스 분리 원칙 인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.
5. DIP(Dependency Inversion Prinsiple) : 의존 역전 원칙 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.

함수형 프로그래밍

수학과 밀접한 연관이 있는 프로그래밍, 방대한 데이터를 빠르게 계산해서 병렬적이고 안정적으로 처리하는 것에 대한 중요성이 부각되면서 주목받게 되었다.
일반적으로 함수들을 적용하고 묶어서 프로그래밍 구성하는 것을 말한다.

  1. 순수함수
    동일한 인자를 넣었을 때 동일한 결과값을 반환하고
    외부의 함수값을 참조하거나, 변경할 수 없다.
    언제 선언이 되어도 외부에 전혀 영향을 받지 않도록 작성해야한다.

  2. 불변성유지(immutable)
    함수에 인자로 전달된 데이터를 변경할 수 없다. 새로운 오브젝트를 만들어서 결과값으로 전달해야 한다.
    side effect(외부상태가 변경으로 예상치못한 에러가 발생하는 것)를 만들지 않기 때문에 여러가지 동시다발적인 멀티 쓰레드에서도 안정적으로 동작할 수 있다.

// 🙅🏻 
let person={ name: 'Jamong', age: '27'};

function increaseAge(person) { 
person.age = person.age + 1;
return person;

// 🙆🏻
let person={ name: 'Jamong', age: '27'};

function increaseAge(person) { 
return {...person, age: person.age + 1}
  
// 불변성 타입이 없는 자바스크립트에서 오브젝트 불변성으로 만들기
let person= Object.freeze({ name: 'Jamong', age: '27'});

function increaseAge(person) { 
return Object.freeze({...person, age: person.age + 1})
  1. if, switch, for X

  2. 함수에 변수를 할당하거나 함수의 인자로 전달하는 리턴할 수 있는 일급함수, 함수 자체를 인자로 전달하거나 함수 안에서 또 다른 함수를 리턴하는 고차함수의 성격을 가진다.


출처: Interview_Question_for_Beginner https://github.com/JaeYeopHan/Interview_Question_for_Beginner/tree/master/Development_common_sense
드림엘리 함수형프로그래밍이 대세다?! (함수형 vs 객체지향) https://www.youtube.com/watch?v=4ezXhCuT2mw
profile
즐거운 도전중입니다:)

0개의 댓글