객체지향의 특성은 4가지다.
- 캡슐화
- 상속
- 추상화
- 다형성
객체지향을 처음 접했을 때 특성 이전에 SOLID원칙을 먼저 접했다. 그래서 SOLID와 객체지향의 특성이 엄연히 다르다는 것을 잘 인지하지 못 했었는데, SOLID는 객체지향의 특성을 더욱 살려 좋은 소프트웨어를 설계하기 위한 원칙이다.
캡슐화
캡슐화는 객체가 책임을 수행하는 단위로써 완전함을 갖는 의미를 가지고 있다. 객체가 어떤 기능을 수행함에 있어, 다른 외부 객체와 협력할 필요가 있을 수도 있다. 이 때 객체가 다른 외부 객체를 의존한다고도 하는데, 가장 이상적인 캡슐화는 이 의존성이 최대한 없도록 만드는 것이다. 가능한 독립적으로 기능을 수행할 수 있는 완전성을 가지는 것이 가장 높은 수준의 캡슐화가 성취된 것이고, 의존성이 있더라도 최대한 느슨하게 만들어 주는 것이 바람직하다.
예시를 살펴보자.
class Human {
Blood blood;
public Blood donate() {
return blood.half();
}
}
class Hospital {
Blood blood;
public void store() {
Human h = new Human();
Blood donated = h.donate();
blood.add(donated);
}
}
사람 클래스로 생성된 인스턴스는 자신의 피를 일정량 헌혈할 수 있다. 이 때, 얼마나 헌혈할지는 병원이 정하는 것이 아니라 사람 본인이 정할 수 있다. 사람은 가지고 있는 피로 헌혈의 기능을 수행할 때 외부에 상관없이 본인이 완전하게 기능을 수행할 수 있어 사람의 상태와 행동이 응집도가 높다. 사람의 행위에 대한 모든 것이 사람 클래스에만 머무르는 것이 객체지향의 캡슐화라는 특징이다.
이러한 독립성을 위한 캡슐화는 최대한 지켜져야 하는 것이지 꼭 모든 외부로의 접근과 외부로부터의 접근을 제한하는 것이 아니다. 객체지향 프로그래밍은 결국 객체들의 협력으로 이루어져있기 때문이다.
병원은 사람이 없으면 혈액을 받지 못 한다. 헌혈을 위해선 사람에 의존해야하는 것이다. 그렇다면 캡슐화가 깨진 것인가? 그렇지 않다. 병원에서 수행하는 책임인 혈액을 보관하는 것은 다른 존재에 의해서 이루어지는 것이 아니다. 보관을 할 때 사람이 필요한 것이지, 사람만 있으면 얼만큼의 혈액을 보관할지는 병원이 스스로 정한다. 병원 역시 캡슐화라는 객체지향의 특성이 보인다.
캡슐화와 정보 은닉이 혼동될 수도 있다. 하지만 둘은 엄연히 다르다. 캡슐화는 객체가 가지는 상태와 행위의 연관성을 높여 객체의 응집도를 높이는 것이 목적이라면, 정보 은닉은 외부에서 해당 객체를 접근할 때 객체의 상태에 대한 접근을 최대한 막는 것이다.
정보은닉
병원에서 마음대로 환자의 피를 가져갈 수 있다고 생각해보자.
class Hospital {
Blood blood;
public void store() {
Human h = new Human();
Blood donated = h.blood.all();
blood.add(donated);
}
}
사람은 자신의 피에 대한 접근을 외부로부터 제한을 하지 않기에 병원이 맘대로 피를 전부 뽑아버릴 수 있다. 이렇게 외부로부터 접근을 막기 위해 접근 제한자로 객체의 상태를 숨겨 정보를 은닉해야한다.
class Human {
private Blood blood;
public Blood donate() {
return blood.half();
}
}
class Hospital {
private Blood blood;
public void store() {
Human h = new Human();
// Blood donated = h.blood.all();
blood.add(donated);
}
}
그렇다면, 캡슐화와 정보 은닉이 혼동되는 이유는 무엇일까? 정보가 은닉이 안되면 기능의 의미가 떨어진다. 사람은 donate()
이라는 메세지를 통해 기능을 수행할 수 있음에도, 병원이 맘대로 피를 가져갈 수 있다. 객체의 기능성이 객체에 머무르는 것이 아니라, 외부 객체가 결정할 수 있게 되는 것이다. 그렇기 때문에, 정보은닉이 잘 안 되어있다면 캡슐화도 깨지게 된다.
캡슐화를 다시 정리하자면, 궁극적으로 객체는 스스로 동작할 수 있는 환경을 갖고 있어야하고, 외부에 의존하거나 외부로부터의 접근을 최대한 제한 하는 것이다.
접근제한자
접근제한자 4가지가 있다.
- private - 객체 내부 접근만 가능
- (friendly) - 같은 패키지 내에서 접근 가능
- protected - 같은 패키지, 상속된 객체에서도 접근 가능
- public - 모두 접근 가능
자바에선 friendly보단 default가 더 익숙한 것 같다. 접근제한자가 아무것도 없을 때 friendly제한이 적용된다. 패키지에서만 가능한 접근은 언제 사용할까?
girl이라는 패키지와 boy라는 패키지가 존재한다고 가정하자. 여자들만의 Secret이 존재하고, 남자들만의 Secret이 존재한다면, 여자들은 여자들만의 비밀에만 접근 가능해야하고 남자들은 남자들만의 비밀에만 접근 가능해야한다. 이 때 각각의 비밀들과 성별의 클래스들을 같은 패키지 안에 두어 패키지에서만 접근 가능하게 만들 수 있다. 이를 패키지 가시성이라고 한다.
References
프로그래머스 백엔드 데브코스
'객체지향 프로그래밍' 카테고리의 다른 글
객체지향의 특성 - 추상화 (0) | 2024.05.22 |
---|---|
객체지향의 특성 - 상속 (0) | 2024.05.21 |
객체지향 프로그래밍(OOP) 이야기 (1) | 2024.05.20 |
단일 책임 원칙 이야기 (2) - 책임의 범주 (1) | 2024.01.21 |
단일 책임 원칙 이야기 (1) - 책임이란 (1) | 2023.11.30 |
객체지향의 특성은 4가지다.
- 캡슐화
- 상속
- 추상화
- 다형성
객체지향을 처음 접했을 때 특성 이전에 SOLID원칙을 먼저 접했다. 그래서 SOLID와 객체지향의 특성이 엄연히 다르다는 것을 잘 인지하지 못 했었는데, SOLID는 객체지향의 특성을 더욱 살려 좋은 소프트웨어를 설계하기 위한 원칙이다.
캡슐화
캡슐화는 객체가 책임을 수행하는 단위로써 완전함을 갖는 의미를 가지고 있다. 객체가 어떤 기능을 수행함에 있어, 다른 외부 객체와 협력할 필요가 있을 수도 있다. 이 때 객체가 다른 외부 객체를 의존한다고도 하는데, 가장 이상적인 캡슐화는 이 의존성이 최대한 없도록 만드는 것이다. 가능한 독립적으로 기능을 수행할 수 있는 완전성을 가지는 것이 가장 높은 수준의 캡슐화가 성취된 것이고, 의존성이 있더라도 최대한 느슨하게 만들어 주는 것이 바람직하다.
예시를 살펴보자.
class Human {
Blood blood;
public Blood donate() {
return blood.half();
}
}
class Hospital {
Blood blood;
public void store() {
Human h = new Human();
Blood donated = h.donate();
blood.add(donated);
}
}
사람 클래스로 생성된 인스턴스는 자신의 피를 일정량 헌혈할 수 있다. 이 때, 얼마나 헌혈할지는 병원이 정하는 것이 아니라 사람 본인이 정할 수 있다. 사람은 가지고 있는 피로 헌혈의 기능을 수행할 때 외부에 상관없이 본인이 완전하게 기능을 수행할 수 있어 사람의 상태와 행동이 응집도가 높다. 사람의 행위에 대한 모든 것이 사람 클래스에만 머무르는 것이 객체지향의 캡슐화라는 특징이다.
이러한 독립성을 위한 캡슐화는 최대한 지켜져야 하는 것이지 꼭 모든 외부로의 접근과 외부로부터의 접근을 제한하는 것이 아니다. 객체지향 프로그래밍은 결국 객체들의 협력으로 이루어져있기 때문이다.
병원은 사람이 없으면 혈액을 받지 못 한다. 헌혈을 위해선 사람에 의존해야하는 것이다. 그렇다면 캡슐화가 깨진 것인가? 그렇지 않다. 병원에서 수행하는 책임인 혈액을 보관하는 것은 다른 존재에 의해서 이루어지는 것이 아니다. 보관을 할 때 사람이 필요한 것이지, 사람만 있으면 얼만큼의 혈액을 보관할지는 병원이 스스로 정한다. 병원 역시 캡슐화라는 객체지향의 특성이 보인다.
캡슐화와 정보 은닉이 혼동될 수도 있다. 하지만 둘은 엄연히 다르다. 캡슐화는 객체가 가지는 상태와 행위의 연관성을 높여 객체의 응집도를 높이는 것이 목적이라면, 정보 은닉은 외부에서 해당 객체를 접근할 때 객체의 상태에 대한 접근을 최대한 막는 것이다.
정보은닉
병원에서 마음대로 환자의 피를 가져갈 수 있다고 생각해보자.
class Hospital {
Blood blood;
public void store() {
Human h = new Human();
Blood donated = h.blood.all();
blood.add(donated);
}
}
사람은 자신의 피에 대한 접근을 외부로부터 제한을 하지 않기에 병원이 맘대로 피를 전부 뽑아버릴 수 있다. 이렇게 외부로부터 접근을 막기 위해 접근 제한자로 객체의 상태를 숨겨 정보를 은닉해야한다.
class Human {
private Blood blood;
public Blood donate() {
return blood.half();
}
}
class Hospital {
private Blood blood;
public void store() {
Human h = new Human();
// Blood donated = h.blood.all();
blood.add(donated);
}
}
그렇다면, 캡슐화와 정보 은닉이 혼동되는 이유는 무엇일까? 정보가 은닉이 안되면 기능의 의미가 떨어진다. 사람은 donate()
이라는 메세지를 통해 기능을 수행할 수 있음에도, 병원이 맘대로 피를 가져갈 수 있다. 객체의 기능성이 객체에 머무르는 것이 아니라, 외부 객체가 결정할 수 있게 되는 것이다. 그렇기 때문에, 정보은닉이 잘 안 되어있다면 캡슐화도 깨지게 된다.
캡슐화를 다시 정리하자면, 궁극적으로 객체는 스스로 동작할 수 있는 환경을 갖고 있어야하고, 외부에 의존하거나 외부로부터의 접근을 최대한 제한 하는 것이다.
접근제한자
접근제한자 4가지가 있다.
- private - 객체 내부 접근만 가능
- (friendly) - 같은 패키지 내에서 접근 가능
- protected - 같은 패키지, 상속된 객체에서도 접근 가능
- public - 모두 접근 가능
자바에선 friendly보단 default가 더 익숙한 것 같다. 접근제한자가 아무것도 없을 때 friendly제한이 적용된다. 패키지에서만 가능한 접근은 언제 사용할까?
girl이라는 패키지와 boy라는 패키지가 존재한다고 가정하자. 여자들만의 Secret이 존재하고, 남자들만의 Secret이 존재한다면, 여자들은 여자들만의 비밀에만 접근 가능해야하고 남자들은 남자들만의 비밀에만 접근 가능해야한다. 이 때 각각의 비밀들과 성별의 클래스들을 같은 패키지 안에 두어 패키지에서만 접근 가능하게 만들 수 있다. 이를 패키지 가시성이라고 한다.
References
프로그래머스 백엔드 데브코스
'객체지향 프로그래밍' 카테고리의 다른 글
객체지향의 특성 - 추상화 (0) | 2024.05.22 |
---|---|
객체지향의 특성 - 상속 (0) | 2024.05.21 |
객체지향 프로그래밍(OOP) 이야기 (1) | 2024.05.20 |
단일 책임 원칙 이야기 (2) - 책임의 범주 (1) | 2024.01.21 |
단일 책임 원칙 이야기 (1) - 책임이란 (1) | 2023.11.30 |