λμλλ μ½λμ λ°©ν₯μ
μ’μ, κ°μ²΄ μ§ν₯μ νλ‘κ·Έλλ°μ μν λ°©λ²λ‘
μ’μ νλ‘κ·Έλλ° μ½λλ λ³κ²½μ΄ μ©μ΄νκ³ , μ μ§λ³΄μμ νμ₯μ΄ μ¬μ΄ μ½λμ΄λ€. μ΄λ¬ν μ½λλ₯Ό μμ±νκΈ° μν΄μλ λ€μκ³Ό κ°μ λ°©λ²λ‘ κ³Ό μμΉμ λ°λ₯΄λ κ²μ΄ μ€μνλ€.
- μ€λ³΅μ μ΅μν: νλμ μμ μ΄ λ€λ₯Έ νλμ μμ μ λλ°ν΄μ μλλ€.
- μ½λ λ³κ²½μ μ©μ΄μ±: μ½λλ νμ μλ²½νμ§ μκ³ μꡬμ¬νμ μμ λ°λ μ μλ€.
- μ¬μ¬μ©μ±: μ λλ μ½λλ λΉμ·νκ±°λ λ€λ₯Έ μꡬμ¬νμλ κ·Έλλ‘ μ¬μ© κ°λ₯νλ€.
ν΄λ¦° μ½λμ κΈ°μ€: λ¨μΌ λͺ©μ κ³Ό μ€μ©, λ¨μ© λ°©μ§
λͺ¨λ λ³μ, ν¨μ, ν΄λμ€λ λͺ νν λͺ©μ μ κ°μ§κ³ , μ€μ©λμ§ μλλ‘ κ΄λ¦¬λμ΄μΌ νλ€. μ΄λ₯Ό μν μ£Όμ μμΉμ λ€μκ³Ό κ°λ€
- DRY (Dont' Repeat Yourself): λμΌν λ‘μ§μ μ¬λ¬ κ³³μ μ€λ³΅νμ§ λ§κ³ , ν κ³³μμλ§ κ΄λ¦¬νλ€.
- KISS (Keep It Simple and Stupid): λ¨μΌ λͺ©μ μ κ°μ§λ©°, κ°λ¨νκ³ λͺ νν μ½λλ₯Ό μμ±νλ€.
- YAGNI (You Ain't Gonna Neet It): λ―Έλμ νμλ₯Ό κ³ λ €νμ¬ μ§λμΉκ² λ§μ κΈ°λ₯μ 미리 ꡬννμ§ μλλ€.
κ°μ²΄μ§ν₯ μ€κ³ μμΉ SOLID
SOLIDλ κ°μ²΄μ§ν₯ μ€κ³μμ μ’μ μ½λ μμ±μ μν λ€μ― κ°μ§ μμΉμ μ μνλ€. μ΄ μμΉλ€μ μ μ°ν μ€κ³μ νμ₯ κ°λ₯ν ꡬ쑰λ₯Ό λ§λλ λ°μ λμμ΄ λλ€.
1. Single Responsibility Principle (SRP) - λ¨μΌ μ± μ μμΉ: νλμ λͺ¨λμ νκ°μ§ μ± μ
- νλμ ν΄λμ€λ λ©μλλ μ€μ§ νλμ μ± μλ§μ κ°μ ΈμΌνλ€.
- λ³κ²½μ΄ μΌμ΄λ κ²½μ°, μ€μ§ ν κ°μ§ μ΄μ λλ¬Έμ λ³κ²½λμ΄μΌ νλ€.
μμ μ½λ
publi class UserService {
private UserRepository userRepository;
private PasswordEncoder passwordEncoder;
public void addUser(String email, String password) {
String encryptedPassword = passwordEncoder.encrypt(password);
User user = new User(email, encryptedPassword);
userRepository.save(user);
}
}
2. Open-Closed Principle (OCP) - κ°λ°© νμ μμΉ: νμ₯μ μ΄λ €μλ€ | μμ μ λ«νμλ€.
- νμ₯μλ μ΄λ €μμ§λ§, μμ μλ λ«ν μμ΄μΌ νλ€.
- νμ₯μ μ΄λ €μλ€: μꡬμ¬νμ΄ λ³κ²½λ λ μλ‘μ΄ λμμ μΆκ°νμ¬ μ ν리μΌμ΄μ μ κΈ°λ₯μ νμ₯
- μμ μ λ«νμλ€: κΈ°μ‘΄μ μ½λλ₯Ό μμ νμ§ μκ³ μ ν리μΌμ΄μ μ λμμ μΆκ°νκ±°λ λ³κ²½
- κΈ°μ‘΄ μ½λλ₯Ό λ³κ²½νμ§ μκ³ , κΈ°λ₯μ μΆκ°ν μ μμ΄μΌ νλ€.
OCPκ° λ³Έμ§μ μΌλ‘ μκΈ°νλ κ²μ μΆμνμ΄λ©°, μ΄λ κ²°κ΅ λ°νμ μμ‘΄μ±κ³Ό μ»΄νμΌ νμ μμ‘΄μ±μ λν κ²μ΄λ€.
- μ»΄νμΌνμ μμ‘΄μ±: μ½λμ ννλ ν΄λμ€λ€μ κ΄κ³λ₯Ό μλ―Ένλ€. → μΈν°νμ΄μ€ λΆλΆ
- λ°νμ μμ‘΄μ±: μ ν리μΌμ΄μ μ€ν μμ μμμ κ°μ²΄λ€μ κ΄κ³λ₯Ό μλ―Ένλ€. → μΈν°νμ΄μ€ λ΄ κ΅¬μ²΄ ν΄λμ€ μ£Όμ
μμ μ½λ
public interface PasswordEncoder {
String encrypt(String password);
}
public class SHA256PasswordEncoder implements PasswordEncoder {
@Override
public String encrypt(String password) {
// SHA-256 μνΈν λ‘μ§
}
}
3. Interface Segregation Principle (ISP) - μΈν°νμ΄μ€ λΆλ¦¬ μμΉ: μΈν°νμ΄μ€ λ΄μ λ©μλ μ΅μ κ°μ
μΈν°νμ΄μ€ λ΄μ λ©μλλ μ΅μν κ°μλ‘(S: ν΄λμ€, λ©μλ κ΄μ - I: μΈν°νμ΄μ€ κ΄μ )
νλμ μΌλ°μ μΈ μΈν°νμ΄μ€ λ³΄λ€ μ¬λ¬ κ°μ ꡬ체μ μΈ μΈν°νμ΄μ€κ° λ«λ€.
λλ©μΈκ°μ κ²μΌλ‘ μΈν°νμ΄μ€λ₯Ό μͺΌκ°μ΄ λμΌλ©΄ νμν ꡬνμ 1κ°μΈλ° ꡬν체μ λλ¨Έμ§ μ°μ§λ μλ κ²λ€κΉμ§ ꡬνν΄μΌνλ€.
μμ )
λΌλ©΄ λμ΄κΈ° κ°μ²΄ - λ¬Όλμ΄κΈ°, μ€νλ£κΈ°, λ©΄λ£κΈ°, νμ°μ΄λ£κΈ°, κ³λλ£κΈ°
- ν μ°μ΄λ£κΈ°, κ³λ λ£κΈ° λ΄ μ무κ²λ ꡬνμ΄ μμ (ν λΉ Empty ꡬν)
- κΈ°λ³Έ λΌλ©΄ λμ΄κΈ°, λΌλ©΄μ κ³ λͺ λ£κΈ° λ±μΌλ‘ μͺΌκ°μ΄μΌν¨.
- ꡬ체μ μΈ μΈν°νμ΄μ€ μ¬λ¬ κ°λ‘ λΆλ¦¬νμ¬ νμν κΈ°λ₯λ§ κ΅¬ννλλ‘ νλ€.
- λΆνμν κΈ°λ₯μ΄ ν¬ν¨λ μΈν°νμ΄μ€λ₯Ό ꡬννμ§ μλλ‘ λ°©μ§νλ€.
μμ μ½λ
public interface PasswordChecker {
String isCorrectPassword(final String rawPw, final String pw);
}
@Component
public class SHA256PasswordEncoder implements PasswordEncoder, PasswordChecker {
@Override
public String encryptPassword(final String pw) {
...
}
@Override
public String isCorrectPassword(final String rawPw, final String pw) {
final String encryptedPw = encryptPassword(rawPw);
return encryptedPw.equals(pw);
}
}
4. Dependency Inversion Principle (DIP) - μμ‘΄μ± μμ μμΉ: μΈν°νμ΄μ€λ‘ ꡬν체λ₯Ό μ°κ²°
μΈν°νμ΄μ€ ꡬν체λ₯Ό μ°κ²°
- (@Service) κ³ μμ€ λͺ¨λ ←μΈν°νμ΄μ€(μΆμν) ← (@Autowired) μ μμ€ λͺ¨λ
- κ³ μμ€ λͺ¨λ: μ μ μ 보λ₯Ό DBμμ κ°μ Έμ¨λ€.(λΉμ§λμ€ κ΄λ ¨, μΆλ ₯(DB)κ³Ό λ©λ€)
- μ μμ€ λͺ¨λ: DBμμ μ μ ν
μ΄λΈμ μ°Ύμ μ 보λ₯Ό λ°ννλ€. (DB, μΆλ ₯κ³Ό κ°κΉλ€)
- DBκ° RDBMSκ° μλλΌ NoSQL μ΄λΌλ©΄ ?
- DBκ° λκΈ°κ° μλλΌ λΉλκΈ°λΌλ©΄?
- μΆλ ₯μ μμ΄μ λ€μν μ νμ§, κ²½μ°μ μ
κ³ μμ€ λͺ¨λμ μ μμ€ λͺ¨λμ ꡬνμ μμ‘΄νμ§ μλλ€λ κ²
= μ μμ€μ΄ μ΄λ»κ² ꡬνλμ΄μλ κ΅³μ΄ μ κ²½μΈ νμκ° μλ€
= μνλ μ μμ€ κ΅¬ν체λ₯Ό κ°μ Έλ€ μ°λ©΄ λλ€.
= μ μμ€μ΄ κΌ λ¬΄μμ΄μ¬μΌλ§ νλ κ²μ μλλ€.
= μ μμ€μ μΈν°νμ΄μ€λ₯Ό ν΅ν΄ λ«λ €μκ³ , μ무 ꡬ체 ν΄λμ€λ§ λ€μ΄μ€λ©΄ μ₯λ‘μ΄λ€.
κ³ μμ€ λͺ¨λμ μ μμ€ λͺ¨λμ ꡬνμ μμ‘΄ν΄μλ μλλ©°, μ μμ€ λͺ¨λμ΄ κ³ μμ€ λͺ¨λμ μμ‘΄ν΄μΌ νλ€λ κ²μ΄λ€.
- κ³ μμ€ λͺ¨λ: μ λ ₯κ³Ό μΆλ ₯μΌλ‘λΆν° λ¨Ό(λΉλμ§μ€μ κ΄λ ¨λ) μΆμνλ λͺ¨λ
- μ μμ€ λͺ¨λ: μ λ ₯κ³Ό μΆλ ₯μΌλ‘λΆν° κ°κΉμ΄(HTTP, λ°μ΄ν°λ² μ΄μ€, μΊμ λ±κ³Ό κ΄λ ¨λ) ꡬν λͺ¨λ
λ°λΌμ κ³ μμ€ λͺ¨λμ μ μμ€ λͺ¨λλ€μ @Autowired νλ€.
- μμ‘΄ μμ μμΉ(D)μ κ°λ°© νμ μμΉ(O)μ λ°μ ν κ΄λ ¨μ΄ μλ€.
- μμ‘΄ μμ μμΉ(D)μμ μμ‘΄μ±μ΄ μμ λλ μμ μ "μ»΄νμΌ μμ " μ΄λ€.
μ 리νμλ©΄:
- κ³ μμ€ λͺ¨λμ μ μμ€ λͺ¨λμ ꡬνμ μμ‘΄ν΄μλ μλλ€.
- μΈν°νμ΄μ€λ₯Ό ν΅ν΄ ꡬν체μ λν μμ‘΄μ±μ μμ μν¨λ€.
5. Liskov Substitution Principle (LSP) - 리μ€μ½ν μΉν μμΉ: "μμ μ" λΆλͺ¨ ν΄λμ€μ λν κ°μ μΆ©μ‘±
"μμ μ" λΆλͺ¨ ν΄λμ€μ λν κ°μ κ·Έλλ‘ μμ ν΄λμ€κ° μ μ λμ΄μΌ νλ€.(κ³κΈμ )
- νμ νμ μ νμ μμ νμ μ λ체 ν μ μμ΄μΌνλ€.
μμ μ νμ ν΄λμ€λ μμ ν΄λμ€μ λͺ¨λ κ°μ μ κ·Έλλ‘ κ°κ³ μμ΄μΌνλ€.
μμ ν΄λμ€λ₯Ό μ¬μ©νλ κ°λ°μκ° κ°μ νλ λͺ¨λ κ²μ μ 곡ν΄μΌν¨.
μμ μ½λ(μλͺ»λ μ€κ³):
public class Rectangle {
private int width, height;
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
}
public class Square extends Rectangle {
@Override
public void setWidth(int size) {
super.setWidth(size);
super.setHeight(size);
}
@Override
public void setHeight(int size) {
super.setWidth(size);
super.setHeight(size);
}
}
Squareλ Rectangleμ μμλ°μμΌ νμ§λ§, setWidthμ setHeightκ° Squareμ λμμ λ§κ°λ¨λ¦΄ μ μλ€. μ΄λ 리μ€μ½ν μΉν λ²μΉμ μλ°νλ μ¬λ‘μ΄λ€.
μ΄λ₯Ό ν΄κ²°νλ μ’μ λ°©λ²μ μμμ μ¬μ©νμ§ μκ³ , ν©μ±(Composition)μ μ¬μ©νλ κ²μ΄λ€.
Squareμ Rectangle λͺ¨λκ° ShapeλΌλ κ³΅ν΅ νμ΄μ€λ₯Ό ꡬννκ³ , κ° λνμ΄ μμ λ§μ λμμ μ μνλ λ°©μμ΄λ€.
μμ μ½λ (LSP μ€μ):
// Shape μΈν°νμ΄μ€ μ μ
public interface Shape {
int getArea();
}
// Rectangle ν΄λμ€λ Shapeλ₯Ό ꡬν
public class Rectangle implements Shape {
private int width, height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
@Override
public int getArea() {
return width * height;
}
}
// Square ν΄λμ€λ Shapeλ₯Ό ꡬννμ§λ§, μμμ μ¬μ©νμ§ μμ
public class Square implements Shape {
private int size;
public Square(int size) {
this.size = size;
}
public void setSize(int size) {
this.size = size;
}
@Override
public int getArea() {
return size * size;
}
}
μ’μ κ°μ²΄μ§ν₯ νλ‘κ·Έλλ° μ½λλ₯Ό μν μμΉ 2κ°μ§
- ꡬνλ³΄λ€ μΈν°νμ΄μ€μ λ§μΆ°μ μ½λ©νλ€.
- ꡬνμ μΈμ λ μ§ λ³κ²½λ μ μμ§λ§, μΈν°νμ΄μ€λ₯Ό ν΅ν΄ μ μ°ν μ½λλ₯Ό μμ±ν μ μλ€.
- μμ보λ€λ ν©μ±(Composition)μ μ¬μ©νμ.
- μμμ μ½λμ κ²°ν©λλ₯Ό λμ΄λ λ°λ©΄, ν©μ±μ νμν κΈ°λ₯μ λμ μΌλ‘ μΆκ°ν μ μμ΄ λ μ μ°νλ€.
λμμΈ ν¨ν΄
λμμΈ ν¨ν΄μ μμ£Ό λ°μνλ λ¬Έμ λ€μ λν μ¬μ¬μ© κ°λ₯ν ν΄κ²°μ± μ μ 곡νλ€. κ° ν¨ν΄μ νΉμ ν μν©μμ ꡬ쑰μ μΌλ‘ ν¨μ¨μ μΈ ν΄κ²°μ± μ μ μνλ©°, μ½λμ μ μ§λ³΄μμ±κ³Ό νμ₯μ±μ λμ΄λ λ°μ κΈ°μ¬νλ€.
- λμμΈ ν¨ν΄ μ’ λ₯
λμμΈ ν¨ν΄:
- μμ± ν¨ν΄: κ°μ²΄μ μμ± λ‘μ§μ μΊ‘μννμ¬ μ μ°μ±μ μ 곡.
- μΆμ ν©ν 리, λΉλ, ν©ν 리 λ©μλ, νλ‘ν νμ , μ±κΈν€
- ꡬ쑰 ν¨ν΄: κ°μ²΄λ ν΄λμ€κ° μ΄λ»κ² μλ‘ κ΄κ³λ λ§Ίκ³ νλ ₯νλμ§λ₯Ό μ μ
- μ΄λν°, λΈλ¦¬μ§, μ»΄ν¬μ§νΈ, λ°μ½λ μ΄ν°, νΌμ¬λ, νλΌμ΄μ¨μ΄νΈ, νλ‘μ
- νμ ν¨ν΄: κ°μ²΄λ€ κ°μ μνΈμμ© λ°©λ²μ μ μ
- μ± μμ°μ, 컀맨λ, μΈν°ν리ν°, μ΄ν°λ μ΄ν°, λ―Έλμμ΄ν°, λ©λ©ν , μ΅μ λ², μ€ν μ΄νΈ, μ€νΈλ ν°μ§, ν νλ¦Ώ λ©μλ, λΉμ§ν°
μΌλ°μ μΌλ‘ νμ μμ λ§μ΄ μΈκΈνκ±°λ μμ£Ό μ¬μ©νλ λμμΈ ν¨ν΄:
- μΆμ ν©ν 리 ν¨ν΄: λ©μΈμ§ μ μ‘μ μν λ‘μ§μ λ§λ€ λ μλ§μ ν νλ¦Ώ, μν©λ€μ 컀λ².
- ν©ν 리 λ©μλ ν¨ν΄: μμ±μκ° μλ μ μ ν©ν 리 λ©μλλ₯Ό ν΅ν κ°μ²΄ μμ±
- λΉλ ν¨ν΄: μμ±μκ° μλ λΉλλ₯Ό ν΅ν κ°μ²΄ μμ±
- μ±κΈν΄ ν¨ν΄
- μ΄λν° ν¨ν΄ / λ°μ»€λ μ΄ν° ν¨ν΄: μ΄λ€ λ©μλλ₯Ό νλ² κ°μΈμ μΆκ°μ μΈ μμ μ νμ₯νμ¬ μ¬μ©ν λ
- νμλ ν¨ν΄: μΌλ°μ μΌλ‘ @Autowired νμ¬ μ¬λ¬ νμ μλΉμ€λ€μ λͺ¨μ μ¬μ©νλ κ²
- νλ‘μ ν¨ν΄: Spring AOP λμ μ리, Spring Data JPAμ @Transactional λμ μ리
- μ΅μ λ² ν¨ν΄: λΈλ‘λμΊμ€ν μ΄ νμν λ
- ν νλ¦Ώ λ©μλ: μΆμ ν΄λμ€λ₯Ό μ¬μ©ν λ μ¬μ©ν μ λ°μ μλ ν¨ν΄
βΉοΈμ°Έκ³
[ASAC 6κΈ° κ°μμλ£]
https://velog.io/@haero_kim/SOLID-%EC%9B%90%EC%B9%99-%EC%96%B4%EB%A0%B5%EC%A7%80-%EC%95%8A%EB%8B%A4
SOLID μμΉ, μ΄λ ΅μ§ μλ€!
κ°μ²΄μ§ν₯ νλ‘κ·Έλλ° μ€κ³ μμΉμ λν΄ μμ보기
velog.io
https://medium.com/@learnstuff.io/single-responsibility-principle-ad3ae3e264bb
Single Responsibility Principle
The Single Responsibility Principle (part of SOLID, by Robert C. Martin 2000) states that a class needs to model a single, consistent…
medium.com
https://www.linkedin.com/pulse/interface-segregation-principle-vagdevi-kommineni-okwcc
Interface Segregation Principle
Definition This principle emphasizes that no client class should be forced to implement the interface methods that it doesn’t use. In other words, do not force any client to implement an interface that is irrelevant to them.
www.linkedin.com
https://medium.com/@learnstuff.io/single-responsibility-principle-ad3ae3e264bb
Single Responsibility Principle
The Single Responsibility Principle (part of SOLID, by Robert C. Martin 2000) states that a class needs to model a single, consistent…
medium.com
'π»DEV-STUDY > Java' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Java] Stream (0) | 2024.10.02 |
---|---|
[Java] Optional (1) | 2024.10.02 |
[Java] Enum (0) | 2024.10.01 |
[Java] Interface / Abstract Class (1) | 2024.10.01 |
[Java] Finalκ³Ό Static (2) | 2024.09.30 |