콘텐츠로 이동

2021 04 22 객체지향

2021-04-21 객체지향

일급 컬렉션

  • 참고: https://jojoldu.tistory.com/412
  • 일급 컬렉션이 뭔가요? - 일급 컬렉션이란, Java의 콜렉션을 포함한 클래스는 다른 멤버변수가 없도록 정의한 클래스입니다. - 사용하려는 콜렉션을 하나의 클래스로 정의해 놓으면서, 해당 콜렉션과 관련한 동작을 모아 놓을 수 있습니다.
  • 왜 일급 컬렉션을 사용했나요? - 사실 일급 컬렉션을 사용한 이유는 객체지향 생활체조에 명시되어 있기 때문입니다. - 이는 일급 컬렉션을 통해 유지/보수/확장에 유리한 객체지향적 설계를 할 수 있다는 반증인데요, - 저 역시 일급 컬렉션을 사용하면서 코드가 객체 지향적으로 변한 것을 느낄 수 있었습니다. - 우선 일급 컬렉션의 가장 큰 장점은 "컬렉션의 상태와 하고자 하는 행위"를 한 곳에 모아둔다는 것인데요. - 이는 곧 하나의 역할을 하는, 즉 하나의 책임을 가지는 클래스를 만들기 수월해집니다. - 단일 책임을 가지는 객체를 설계함으로써, 클래스가 응집도가 높도록 설계할 수 있습니다. - 왜 응집도가 높으면 객체지향적이죠? - 하나의 클래스가 다양한 책임을 가지면 유지/보수/확장에 불리해지기 때문입니다. - 하나의 클래스가 다양한 책임을 가진다는 것은, 요구 사항의 변화에 따라 같이 변동되야할 부분이 많다는 것을 뜻합니다. - 또한 객체들의 협력으로 구성된 객체지향 프로그래밍에서 하나의 객체가 많은 책임을 들고있다면, - 해당 클래스에 의존하고 있는 다른 클래스에게도 영향을 주는데요. - 여러개의 책임을 하나의 클래스가 들고있다면, 요구사항의 변화에 따라 주구장창 많은 클래스를 고치는 결과로 이어지고, - 이는 곧 절차지향적인 코드로 변화시킵니다.
  • 일급 컬렉션의 장단점이 무엇인가요? - 우선 비즈니스에 종속된 자료구조를 만듭니다. - 주어진 조건으로만 생성할 수 있는 자료구조를 만들어 Validation을 클래스에서 처리해줄 수 있고, - 의도에 맞게 자료구조를 제어하는 메서드를 통해 개발자 본인이 필요한 자료구조를 쉽게 만들어낼수 있습니다. - 이는 또한, 불변성을 쉽게 보장할 수 있도록 합니다. - 불변성을 보장함으로써, 멀티스레드 환경에서 개발자의 의도와 다르게 코드가 돌아가는 사이드 이펙트를 최소화 하는데요. - 컬렉션의 값을 변경할 수 있는 메서드가 없는 컬렉션을 만들면 일급 컬렉션을 불변 컬렉션으로 만들 수 있습니다. - 또한 추가적으로 컬렉션에 이름을 붙여 가독성을 높일 수 있습니다.

정적 팩토리 메서드

  • 정적 팩토리 메서드가 뭔가요? - 객체 생성을 담당하는 역할을 클래스 메서드로 따로 분리해 놓은 것을 뜻합니다.
  • 생성자로 잘 객체 생성할 수 있는데 왜 필요하죠? - 저는 클래스를 객체의 관리자라고 생각하고 접근하는 것이 좋다고 생각합니다. - 하지만 생성자는 이를 100프로 수행해 내지 못하는 경우들이 있었습니다. - 체스 Team 예시 - 또한 캐싱 기법을 적용하여, 매번 new를 통해 메모리 공간을 차지시켜 객체를 반환하는 것이 아닌, 필요한 객체만 반환하도록 할 수 있습니다. - 또한 하위 자료형 객체를 반환하게 할 수도 있습니다.
  • 정적 팩토리 메서드의 장단점이 뭔가요? - 장점 - 우선 이름을 가집니다. - 이는 생성자에서는 할 수 없었던 것으로 코드의 가독성을 높입니다. - 호출시 마다 새로운 객체를 생성할 필요가 없다. - 이것도 클래스가 객체의 관리자 - 프로그램 내에서 필요한 객체를 미리 생성해두고, 이를 반환하는 것이 가능하다. - Java의 Integer? - 하위 자료형 객체를 반환할 수 있음 - 하위 자료형 객체를 반환할 수 있는게 뭐가 좋죠? - 다형성을 제공하기 때문 - 객체 생성을 캡슐화 할 수 있음 - 생성자를 클래스 메서드안으로 숨겨, 내부 상태를 외부에 드러내지 않고 객체 생성을 가능케 한다. - 단점 - 생성자를 private으로 만들고 정적 팩토리 메서드만 있다면, 상속이 불가능

객체 생성의 캡슐화

  • 왜 객체 생성을 캡슐화 시켰을까요? - 객체 생성을 생성자가 아닌, 정적 팩토리 메서드를 통해서 할 수 있어요. - 저는 이렇게 함으로써, 클래스를 객체를 찍어내는 틀이 아닌, 객체의 관리자로써의 역할을 더 수행할 수 있다고 생각해요. - 예를 들어서 체스 미션에서 Team이라는 클래스에서 Team 객체를 만들어낼때, 저는 WhiteTeam과 BlackTeam 두가지 팀만 필요했어요. - 이를 정적 팩토리 메서드로 제공하여, 생성자를 감추어, 의도에 알맞지 않은 Team이 생성되는 것을 미연에 방지할 수 있었어요.
  • 캡슐화는 애초에 뭘까요? - 데이터의 은닉을 말해요. - 생성자를 클래스의 메서드 안으로 숨기면서 내부 상태를 외부에 드러낼 필요 없이 객체 생성 인터페이스를 단순화 시킬 수 있어요.

응집도와 결합도

  • 응집도와 결합도에 대해 설명해주세요 - 응집도란, 모듈 내부의 요소들이 하나의 책임/목적을 위해 연결되어있는 집중 정도입니다. - 결합도란, 모듈과 모듈간의 상호 의존 정도입니다. - 독립적인 모듈이 되기 위해서는 응집도는 강하고, 결합도는 약해야 합니다.
  • 응집도가 높고, 결합도가 낮으면 왜 좋은 객체이죠? - 객체 지향 프로그래밍을 지향해야 하는 이유는, 대규모 소프트웨어의 유지/보수/확장에 유리하기 때문이라고 생각합니다. - 객체 지향 프로그램은 각자의 역할과 책임이 있는 객체들이 상호 협력을 하면서 작성되어지는데요. - 여기서 각 객체들은 각자의 역할을 충실히 해낼 의무가 있습니다. - 응집도는 모듈 내부의 기능적인 집중 정도로써, 응집도가 높은 객체를 작성한다면, 단일 책임 원칙에 굉장히 잘 부합되는 코드를 작성할 수 있어요. - 단일 책임 원칙이 뭐죠? - 클래스는 단 한개의 책임을 가져야 한다는 SOLID 원칙 중의 SRP를 의미합니다. - 하나의 객체가 하나의 책임을 들고 있음으로써, 해당 클래스의 변화로 인한 다른 객체의 수정을 최소화 할 수 있어요. - 아무래도 하나의 객체가 여러 역할을 수행하고 있으면, 더 많은 객체와 의존관계를 맺거든요. - 결합도는 모듈과 모듈간의 상호 의존 정도에요. - 의존이란 것은 양면성이 있어서 하나가 바뀌면, 다른 것도 변해야할 소지가 많아져요. - 결합도를 최대한 낮추면, 하나의 클래스의 변화가 또다른 클래스로 이어지는 것을 최소화 할 수 있어요.

LSP

  • SOLID원칙 중 LSP는 뭔가요? - LSP는 리스코프 치환 원칙으로써, 정의는 "상위 타입의 객체를 하위 타입의 객체로 치환해도, 상위 타입을 사용하는 프로그램은 정상 작동 해야한다" 입니다.
  • LSP는 왜 중요한가요? - LSP는 OCP를 지원하는 원칙입니다. - 개방폐쇄 원칙을 준수함으로써, 확장에 유리한 코드를 만들 수 있었습니다. - 기능을 사용하는 코드는 최대한 건들지 않은 상태에서, 기능들을 확장해 나갈 수 있었죠. - OCP는 다형성과 추상화를 통해서 구현해 낼 수 있는데요. - LSP는 다형성을 강조한 원칙입니다. - 하위 타입의 객체를 상위 타입을 대신하여 사용함에 있어서 프로그램에서 에러가 발생하지 않도록 해야한다는 것이에요. - 이를 만족시키기 위해, 1. 하위 타입 객체에서 오버라이딩 된 메서드는, 상위 타입 객체에서 지정한 매개변수를 받아야 한다는 것과, 2. 하위 타입 객체에서 오버라이딩 된 메서드는, 상위 타입 객체에서 지정한 리턴 값의 범위 내에 있어야 한다는 것을 준수해야 해요.
  • SOLID 설명해봐요 - SOLID는 객체 지향 설계의 가이드라인 역할을 해줄 수 있는 원칙이라고 생각합니다. - 객체 지향 설계란, 유지/보수/확장에 유리한 설계를 뜻하는데요. - SRP/ISP는 객체가 커지지 않도록, - OCP/LSP/DIP는 변화에 유연한 코드를 작성하도록 도와줍니다.