건물 구조 👍 건물 자재 👎 => 잘 건축된 건물?
건물 자재 👍 건물 구조 👎 => 잘 건축된 건물?
SOLID 원칙들은 소프트웨어 작업에서 프로그래머가 소스 코드가 읽기 쉽고 확장하기 쉽게 될 때까지 소프트웨어 소스 코드를 리팩터링하여 코드 냄새를 제거하기 위해 적용할 수 있는 지침이다.
소프트웨어는 본래의 의미대로 부드러워야합니다. 이는 프로그래밍 세계에서 곧 변경이 용이하다는 뜻으로 받아집니다.
변경이 용이하려면 형태에 독립적이어야합니다. 각 코드간의 의존성이 옅어야한다는 뜻입니다.
코드간의 의존성이 옅어지면 코드를 이해하기 쉬워집니다. 코드를 이해하기 쉬워지면 이후 유지보수에 유리합니다.
유지보수에 유리하다는 것은 곧 그 소프트웨어는 부드럽다 (변경이 용이하다)는 것으로 귀결됩니다.
모든 클래스 혹은 메소드는 각각 하나의 책임만 가져야 한다.
와인 오프너 사용하려고 함.
와인 오프너만 따로 분리해서 만들게 되면 위와 같은 일 X, 더군다나 와인 오픈 기능만큼은 확실하게 처리 O
소프트웨어 개체는 확장에는 열려 있어야하고, 변경에는 닫혀 있어야 한다.
평일에는 차 타고 출퇴근하는데.. 주말에는 캠핑카를 이용한 캠핑도 하고싶어!
그럼 지금 타던 차를 냅두고 캠핑카를 하나 더 사야할까?
내 차에 무언가를 달 수 있는 기능만 있으면 트레일러도 달고 다른 것도 달 수 있다!
좀 더 쉽게 설명해서 새로운 기능의 추가가 일어 났을때에는 기존코드의 수정 없이 추가가 되어야 하고, 내부 매커니즘이 변경이 되어야 할때에는 외부의 코드 변화가 없어야 한다는 의미입니다.
자식 클래스는 부모 클래스에서 가능한 행위를 수행할 수 있어야 한다.
자동차라는 클래스의 자식은 슈퍼카, 오픈카, 앰뷸런스가 될 수 있지만 헬리콥터는 이동수단이라는 공통점만 있을 뿐 날개, 비행이라는 메소드가 없다.
=> LSP를 지키지 않는다면 Car 클래스에 슈퍼카, 오픈카에서 사용하지도 않는 헬리콥터 관련 메소드를 추가해야하고 이는 앞으로 side effect를 발생시킬 가능성이 높다.
사용자가 필요하지 않은 것들에 의존하게 되지 않도록, 인터페이스를 작게 유지해야한다.
A: B씨, 드라이버 좀 가져와주실 수 있나요?
B: 네 물론이죠! 여기요
A: 아... 감사합니다.
실제 사례
// lazy, 한 기능을 사용하기 위해 모든 패키지를 부름
import _ from 'lodash-es';
const uniq = _.uniqBy(concat, 'id');
// tree-shaking
import { uniqBy } from 'lodash-es';
const uniq = uniqBy(concat, 'id');
고수준 정책을 구현하는 코드는 저수준 세부사항을 구현하는 코드에 절대 의존해서는 안 된다.