SOLID 5가지 원칙을 알아보자
SOLID 원칙은 객체 지향 프로그래밍에서 좋은 소프트웨어 디자인을 위한 5가지 원칙으로, 개발자들이 유지 보수성이 높고 확장 하기 좋고, 재사용성이 높은 소프트웨어를 만들 수 있도록 도와줍니다. 🙂
원칙을 준수하지 않을 경우 코드의 변경이 한 부분에서 다른 부분으로 의존되는 경우가 많아져 유지보수하기 어려워지는 문제가 있고, 새로운 요구사항이 생기면 기존의 코드를 수정해야 할 경우가 많아져 확장성이 떨어집니다. 기능이 중복되는 경우도 생겨 재사용성이 떨어지는 문제도 발생합니다.
그렇기에 우리는 SOLID 원칙을 더욱 더 준수해야 합니다. SOLID 원칙을 지킬 시 코드의 변경이 한 부분에서만 일어나기 때문에 유지보수성이 좋아지고, 새로운 요구사항이 생기더라도 기존의 코드를 수정하지 않고 확장할 수 있어서 확장성이 좋아집니다. 또한 코드의 중복을 제거하고 재사용성을 높여서 효율적인 개발이 가능해지고 코드가 단순해지기 때문에 테스트하기 쉬워지고 성능도 향상됩니다.
📝 SOLID 5가지 원칙을 알아보자
📌 SRP (Single Responsibility Principle) - 단일 책임 원칙
단일 책임 원칙은 각 클래스나 함수는 한 가지 역할만 수행해야 한다는 원칙입니다.
이렇게 구현하면 코드의 가독성이 좋아지고 유지보수도 쉬워집니다.
또한, 클래스나 함수의 기능을 확장할 때 기존 코드를 수정하지 않아도 되므로 코드의 안정성도 높아집니다.
📌 OCP (Open/Closed Principle) - 개방-폐쇄 원칙
개방-폐쇄 원칙은 확장에는 열려있고 변경에는 닫혀있어야 한다는 원칙입니다.
이것은 새로운 요구사항이 추가될 때 기존의 코드를 수정하지 않고 확장할 수 있도록 코드를 작성해야 한다는 것을 의미합니다.
이를 통해 기존 코드의 안정성을 유지할 수 있습니다.
📌 LSP (Liskov Substitution Principle) - 리스코프 치환 원칙
리스코프 치환 원칙은 상위 클래스의 인스턴스는 하위 클래스의 인스턴스로 대체 가능해야 한다는 원칙입니다.
이것은 하위 클래스에서는 상위 클래스에서 정의한 메소드와 속성을 그대로 사용할 수 있어야 한다는 것을 의미합니다.
리스코프 치환 원칙을 지켜 구현하면 상속 관계에서 코드를 재사용할 수 있으며, 새로운 기능을 추가할 때도 상위 클래스를 수정하지 않아도 됩니다.
📌 ISP (Interface Segregation Principle) - 인터페이스 분리 원칙
인터페이스 분리 원칙은 하나의 인터페이스보다는 작은 단위의 여러 개의 인터페이스가 더 좋다는 원칙입니다.
이것은 클래스나 모듈이 필요로 하는 기능만 제공되도록 인터페이스를 분리해야 한다는 것을 의미합니다.
인터페이스 분리 원칙을 지켜 구현하면 인터페이스가 간단해져서 클래스나 모듈의 구현이 쉬워지며, 불필요한 코드를 제거할 수 있습니다.
📌 DIP (Dependency Inversion Principle) - 의존성 역전 원칙
의존성 역전 원칙은 고수준의 모듈은 저수준의 모듈에 의존해서는 안되며, 둘 모두 추상화된 인터페이스에 의존해야 한다는 원칙입니다.
이렇게 구현하면 클래스나 모듈의 구현이 간단해지며, 코드의 재사용성도 높아집니다.
또한, 의존성을 인터페이스로 분리함으로써 코드 변경에 대한 영향을 최소화할 수 있으니 유지보수성이 향상됩니다.
🧐 자바스크립트도 SOLID 원칙을 지켜 작성할 수 있을까?
자바스크립트도 SOLID 원칙을 어느정도 지켜서 코드를 작성할 수 있어요. 😀
그동안 필자를 힘들게 했던 유효성 검증 기능을 SOLID 원칙을 최대한 지켜 작성해 보았습니다.
구현 조건은 다음과 같습니다.
- 해당 데이터 유효성 체크
- 유효성을 통과하지 못할 시 에러 메세지 노출
- 유효성을 통과한 경우 에러 메세지 제거
function Validator() {
function validateMyName(name) {
/* 조건
01. 2글자 이상
02. 타입이 string 형태일 것
03. 값이 무조건 있어야 함
*/
if(isNull(name)){
return false;
}
return typeof name === "string" && name.length >= 2;
}
function validatePassword(password) {
/* 조건
01. 8글자 이상
02. 값이 무조건 있어야 함
*/
if(isNull(password)){
return false;
}
return password.length >= 8;
}
function validateEmail(email) {
/* 조건
01. ..@.. 구조로 작성
02. 값이 무조건 있어야 함
*/
if(isNull(email)){
return false;
}
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
function validateMyTel(tel) {
/* 조건
01. 000-0000-0000 / 000-000-0000 구조로 작성
02. 11~12 자로 구성
03. 값이 무조건 있어야 함
*/
if(isNull(tel)){
return false;
}
if(tel.length < 11 && !tel.length > 12){
return false;
}
return /\d{3}\d{3,4}\d{4}$/.test(tel);
}
function isNull(value){
if(value == undefined || value == null || value.length == 0){
return true;
}
return false;
}
return {
validateMyName,
validatePassword,
validateEmail,
validateMyTel
};
}
먼저 validation을 체크해주는 함수를 만들었습니다.
입력값이 모두 있어야 하기 때문에 isNull 함수를 만들어 공통으로 사용할 수 있게 만들어주었습니다. 🙂
function UserService(validator) {
function registerUser(user) {
removeMassage();
if (!validator.validateMyName(user.name)) {
const nameErrorEl = document.querySelector("[data-info='myName']");
errorMassage(nameErrorEl, "이름을 다시 확인해주세요.");
}
if (!validator.validatePassword(user.password)) {
const passwordErrorEl = document.querySelector("[data-info='password']");
errorMassage(passwordErrorEl, "비밀번호를 다시 확인해주세요.");
}
if (!validator.validateEmail(user.email)) {
const emailErrorEl = document.querySelector("[data-info='email']");
errorMassage(emailErrorEl, "이메일을 다시 확인해주세요.");
}
if (!validator.validateMyTel(user.tel)) {
const telErrorEl = document.querySelector("[data-info='myTel']");
errorMassage(telErrorEl, "전화번호를 다시 확인해주세요.");
}
}
function errorMassage(el, massage){
el.innerText = massage;
}
function removeMassage(){
const errorEl = Array.from(document.getElementsByClassName("error"));
errorEl.map(el => el.innerText = "");
}
return {
registerUser,
};
}
이어서 Service 로직을 작성합니다.
const validator = Validator();
const userService = UserService(validator);
const validCheckBtnEl = document.getElementById("validCheckBtn");
validCheckBtnEl.addEventListener("click", function(){
const myNameValue = document.getElementById("myName").value;
const passwordValue = document.getElementById("password").value;
const emailValue = document.getElementById("email").value;
const myTelValue = document.getElementById("myTel").value;
userService.registerUser({ name: myNameValue, password: passwordValue, email: emailValue, tel: myTelValue });
})
작성한 함수와 DOM을 상수에 넣어 함수를 실행시킵니다.
📝 SOLID 원칙을 공부하며…
지금까지 SOLID 원칙
을 지켜 코드를 작성해보았습니다.
하나의 기능만을 동작할 수 있게 작성하여 코드의 재사용성이 높아졌고, 기존 코드를 수정하지 않고 확장할 수 있어서 확장성이 높아졌습니다.
만약 위 코드에서 주소 검증을 추가하게 된다면 기존 코드를 수정할 필요없이 주소를 검증하는 코드만 작성해주면 된답니다. 😀
이번 공부를 통하여 더욱 더 효율적인 코드를 짤 수 있도록 노력해야겠습니다.
포스팅을 읽어주셔서 감사합니다 😀