PP: 절차적 프로그래밍
OOP : 객체지향 프로그래밍
Dog라는 클래스가 존재하고, name 필드와 bark()라는 메소드를 가지는 것이다.Account라는 클래스가 있다고 가정하자.Account에는 name, number, amount 등이 있을 것이다.withdraw(), save() 등이 있을 것이다.Account라는 클래스를 만들었고 이 것이 캡슐화이다.amount를 아무나 접근 가능하다면? 문제가 발생할 것이다. amount 값만 바꿔주면 되기 때문이다.amount를 private로 만들어주고 getter, setter나 다른 메소드 등을 통해서 접근하게 한다면 amount를 실수로 수정하는 일이 없을 것이다. 이 또한 캡슐화이다.Account의 save()를 호출한다고 save()의 내용을 알 수 있는가? 그것 또한 아니다. 이 것또한 캡슐화이다.save() 또는 find() 등을 통하여 데이터를 저장하고, 읽고, 업데이트하고, 삭제할 것이기 때문이다.Repository라는 인터페이스를 만들고, LocalRepository, MySQLRepository, CSVRepository와 같이 구현할 것이다.Repository에 메소드를 정의하고 나머지 구현체들에서 오버라이딩할 것이다. 이 것이 추상화이다.Repository라는 인터페이스를 만들었기 때문이다.add()라는 함수가 있다고 가정하자.add(int num1, int num2), add(int num1, int num2, int num3)가 존재하고 두 메소드 모두 인자로 전달된 수들을 더해서 반환한다.add()인데 인자의 개수에 따라 두 수의 합, 세 수의 합으로 바뀌게 된다. 이 것이 다형성이다.ArrayList는 List를 구현한 AbstractList를 상속한다. LinkedList도 마찬가지이다.List여도 다른 형태를 가질 수 있고 이 또한 다형성이다.List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new LinkedList<>();TV 클래스가 존재한다. 이 TV는 현재 QHD 화질이다.TV를 UHD로 업데이트 했다.TV를 상속받아 QHDTV를 만들고, 또 TV를 상속받아 UHDTV를 만든다. 그렇다면 QHD, UHD 모두 사용 가능하다.앞서 설명한 4가지가 OOP의 특징 이었다면, 이번엔 OOP의 원칙이다.
5대 원리들의 앞글자를 따와 SOLID라 부른다.
SRP(Single Reponsibility Principle)
Naver라는 클래스가 존재한다고 가정하자.Naver는 가지고 있는 책임이 너무나도 많다.NaverWebtoon, NaverBlog 등으로.OCP(Open Close Principle)
Repository를 다시 가져와 보자.Repository로 추상화를 하지 않았다고 가정해보자.LocalRepository만 존재 했다.LocalRepository를 MySQLRepository로 변경할 것이다.Repository라는 인터페이스를 가지고 다양한 형태의 저장소를 확장시켜야 하는 것이다.LSV(The Liskov Substitution Principle)
ArrayList와 LinkedList를 가져와 보자.add(ArrayList list)라는 메소드가 존재한다 이 메소드는 list에 무언가를 추가한다. 그렇다면 이 메소드의 인자로 LinkedList를 사용할 수 있는가?add(List list)라는 메소드가 존재한다. 이 메소드는 둘 다 사용 가능한가?ISP(Interface Segregation Principle)
PhoneService 라는 인터페이스가 있다고 가정하자. PhoneService에는 이 기능들이 모두 포함될 것이다. 현재로 DMB, 라디오 기능이 들어간 스마트폰도 존재하기 때문이다.DMBService, RadiService, MessageService 등과 같은 인터페이스로 불리시켜 하나의 책임을 가지게 만드는 것이 ISP 이다.DIP(Dependency Inversion Principle)
public class KakaoLogin {
String login() {
return "Kakao";
}
}
public class SocialLoginService {
private KakaoLogin login;
public void setLogin(KakaoLogin login) {
this.login = login;
}
public void login() {
return login.login();
}
}
SocialLoginService또한 변경해야 할 것이다.public class KakaoLogin implements Login{
String login() {
return "Kakao";
}
}
public class NaverLogin implements Login{
String login() {
return "Naver";
}
}
public class SocialLoginService {
private Login login;
public void setLogin(Login login) {
this.login = login;
}
public void login() {
return login.login();
}
}
SocialLoginService의 login 필드만 setter를 사용하여 원하는 소셜 로그인을 넣어주면 된다.