Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 래퍼타입
- toLowerCase()
- while과 two-pointer
- 동일성과 동등성
- 자바 최대공약수
- 자바 최소공배수
- StringBuilder
- 자바 유클리드
- 프로그래머스 레벨1
- 스프링환경설정
- 최대공약수
- 최소공배수
- islowercase()
- 모던자바
- isuppercase()
- 베주계수
- sql 데이터형 변환
- stringbuilder의 reverse()
- 스프링뼈대
- 스프링
- 자바 스트링
- string과 stringbuilder
- git 컨벤션
- 최대공약수와 최소공배수
- ineer join
- addDoc
- string
- replaceAll()
- Git사용법
- 유클리드호제법
Archives
- Today
- Total
주노 님의 블로그
[Spring] 객체지향 설계의 5가지 원칙 (SOLID) 본문
블로그 정리, 깃허브 업로드
Q: 강의 수강한 내용을 블로그에 정리하고 싶어요! + 깃허브에 코드를 올려도 될까요?
학습한 내용을 본인의 생각으로 요약하고 정리하는 것은 괜찮습니다.
예제 코드나 강의자료도 설명을 위해서 일부분 발췌하는 것은 괜찮습니다.
출처는 해당 강의 링크를 꼭 남겨주세요.
유료 강의입니다. 따라서 코드 전체를 오픈하면 안됩니다. 깃허브를 사용한다면 혼자서 볼 수 있도록 private으로 사용해주세요.
아래 강의는 인프런 김영한님의 스프링 핵심 원리 - 기본편 에서 발췌한 내용입니다
SOLID는 객체지향 프로그래밍을 구현하는데 중요한 5가지 원칙으로
Single Responsibility Principle : 단일 책임의 원칙
Open / Close Principle : 개방-폐쇄 원칙
Liskov Subsitution Principle : 리스코프 치환 원칙
Interface Segregation principle : 인터페이스 분리 원칙
Dependency Inversion Principle : 의존관계 역전 원칙
가 있다
- SRP (Single Responsibility Principle) - 단일 책임의 원칙
한 클래스는 하나의 책임만 가져야 한다, 클래스 하나가 하나의 기능만 수행을하며.
변경이 있을때 파급 효과가 적으면 단일 책임의 원칙을 잘 지킨것이다
하지만 위 책임이라는 기준이 모호 할 수 있다.
public class User { private String name; private String email; public void setName(String name) { this.name = name; } public void setEmail(String email) { this.email = email; } public void saveToDatabase() { // 데이터베이스에 사용자 정보 저장 } public void sendEmailNotification() { // 이메일 알림 전송 } }
위는 user 클래스 안에 이메일 알림전송, 데이터베이스에 사용자 정보를 저장하는 기능까지
가지고 있는것을 볼 수 있다
public class User { private String name; private String email; public void setName(String name) { this.name = name; } public void setEmail(String email) { this.email = email; } } public class UserRepository { public void saveToDatabase(User user) { // 데이터베이스에 사용자 정보 저장 } } public class EmailService { public void sendEmailNotification(User user) { // 이메일 알림 전송 } }
이렇게 유저클래스, 유저 레파지토리, 이메일서비스를 분리함으로써 단일 책임의 원칙을 준수한것을 볼 수 있다. - OCP( Open / Close Principle) - 개방 폐쇄의 원칙
확장에는 열려 있으나, 변경에는 닫혀 있어야한다.
어떤 기능을 추가한다고, 내부 기능을 바꾸는것을 지양한다는 뜻이다
다형성을 이용하면 소프트웨어를 확장에는 열려있으나 변경에는 닫혀 있게 구현 할 수 있다
기존코드에서 다른코드로 변경을 한 상황이다. 이는 OCP원칙을 깨는 일이다
객체를 생성하고, 연관관계를 맺어주는 별도의 조립 및 설정자가 필요하다 << 이는 스프링이 지원하는 기능이다. - LSP(Liskov Subsitution Principle) - 리스코프 치환 원칙
프로그램 객체는 프래그램의 정확성을 깨트리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야한다.
다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야한다는것.
서브 타입은 언제나 자신의 기반 타입(부모 클래스)로 대체할 수 있어야한다.
프로그램의 객체들이 부모 클래스 타입의 객체로 동작하도록 설계되어있다면
만약 부모객체가 없어도 자식 클래스 객체 만으로 문제없이 동작해야한다는 것이다
public class Bird { public void fly() { System.out.println("Flying"); } } public class Ostrich extends Bird { @Override public void fly() { throw new UnsupportedOperationException("Ostriches can't fly"); } }
위 클래스를 보면 부모 클래스를 상속 받았지만
부모클래스의 메서드와 맞지 않는 메서드가 생길 수 있다
public abstract class Bird { public abstract void move(); } public class FlyingBird extends Bird { @Override public void move() { System.out.println("Flying"); } } public class Ostrich extends Bird { @Override public void move() { System.out.println("Running"); } }
이렇게 변경하면 부모 클래스의 어떤 자식이라도 구현할 수 있다 - ISP(Interface Segregation principle) - 인터페이스 분리 원칙
특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나보다 낫다
인터페이스의 기능이 명확해지고 유연성이 높아진다
클라이언트가 자신이 사용하지 않는 메서드에 의존하지 않도록 한다
public interface Worker { void work(); void eat(); } public class HumanWorker implements Worker { @Override public void work() { // 사람 작업 코드 } @Override public void eat() { // 사람 식사 코드 } } public class RobotWorker implements Worker { @Override public void work() { // 로봇 작업 코드 } @Override public void eat() { throw new UnsupportedOperationException("Robots don't eat"); } }
위 코드 예시를 보면 로봇은 먹을 필요는 없지만 인터페이스를 상속받아 eat을 구현해야한다
public interface Workable { void work(); } public interface Eatable { void eat(); } public class HumanWorker implements Workable, Eatable { @Override public void work() { // 사람 작업 코드 } @Override public void eat() { // 사람 식사 코드 } } public class RobotWorker implements Workable { @Override public void work() { // 로봇 작업 코드 } }
위와같이 인터페이스를 작업, 먹기를 분리하면 필요없는 인터페이스의 메서드를 사용하지 않을 수 있다. - DIP(Dependency Inversion Principle) - 의존관계 역전 원칙
고수준 모듈은 저수준 모듈에 의존해서는 안된다. 둘다 추상화에 의존해야한다
추상화는 구체적인 사항에 의존해서는 안된다. 구체적인 사항이 추상화에 의존해야한다.
클라이언트 코드가 구현 클래스를 바라보지말고 인터페이스에 의존하라는 뜻
예를들어 운전자는 자동차 역할 그 자체에 대해서 알아야하는거지, k3에 대해 알라는건 아니다
public class LightBulb { public void turnOn() { System.out.println("LightBulb on"); } public void turnOff() { System.out.println("LightBulb off"); } } public class Switch { private LightBulb lightBulb; public Switch(LightBulb lightBulb) { this.lightBulb = lightBulb; } public void operate() { lightBulb.turnOn(); } }
위 코드를 보자 switch 클래스는 LightBulb에 많이 의존하고 있는 모습을 볼 수 있다
만약 LightBulb를 변경하면, Switch클래스도 변경해야한다
public interface Switchable { void turnOn(); void turnOff(); } public class LightBulb implements Switchable { @Override public void turnOn() { System.out.println("LightBulb on"); } @Override public void turnOff() { System.out.println("LightBulb off"); } } public class Fan implements Switchable { @Override public void turnOn() { System.out.println("Fan on"); } @Override public void turnOff() { System.out.println("Fan off"); } } public class Switch { private Switchable device; public Switch(Switchable device) { this.device = device; } public void operate() { device.turnOn(); } }
고수준 모듈 switch와 저수준 모듈 bulb는 이제 인터페이스에 의존하며, 구체적인 사항(클래스)은
추상화(인터페이스)에 의존하는것을 볼수 있다.
'공부 > Spring' 카테고리의 다른 글
[JPA] JPA에 대해서 (0) | 2024.08.19 |
---|---|
[Spirng] 8. AOP(관점 지향 프로그래밍), 프록시 (0) | 2024.07.30 |
[Spirng] 7. Spring 데이터베이스 연동 - 스프링 데이터 Jpa (0) | 2024.07.30 |
[Spirng] 7. Spring 데이터베이스 연동 - JPA (0) | 2024.07.29 |
[Spirng] 7. Spring 데이터베이스 연동 - JDBCTemplate (0) | 2024.07.29 |