[리팩토링1] 모듈화 , 모달

하율찬·2024년 1월 18일
0

리팩토링

목록 보기
1/1
post-thumbnail

회사 시즌중에는 굉장히 바빴기 때문에 프로젝트를 우선적으로 출시한다는 생각으로 빠르게 움직여, 3개의 프로젝트를 기한내에 마무리하고나니, 내가 잘하고있는가에 대한 의문과함께 리펙토링을 해야겠다는 생각이 강하게들어 리팩토링을 시작하였습니다.

나는 (사수가 없는)주니어인데, 리펙토링한다고 달라질까? 라는 의문이 있어 CTO님한테도 상담을 요청했었다.
CTO님은 그럼, 물론이지 지금의 너와 프로젝트 이전의 너는 다르다고 격려해주셨다.

(일단 가보자고, 현재 회사의 개발문화는 내가 선도한다.(패기))

모듈화

global하게 어디에나 부품처럼 사용될 수 있는 것

모듈화에서 가장중요한 키워드는 재사용성, 독립성이라 생각한다.

직관적으로 디자이너와 함께 가장 쉽게 자주 이야기한 컴포넌트인 모달 컴포넌트가 떠올라 모달 컴포넌트를 모듈화에 중점으로 리팩토링을 진행하였다.

굳이 나누자면 크게 2단계로 필터링 되었다.

재사용성과, 독립성을 둘다 생각하여 한번 걸르고, 한번 리팩토링된 코드를 보고 이게 최선인가? 라는 생각을 했다. (아무래도 첫 리팩토링이며, 기술적으로 부족하기에 더 꼼꼼해야한다.)

현재 모달컴포넌트는 다음과 같은 기능을 한다.

부모컴포넌트에서 제목, 본문 내용, 버튼1의 (이름,스타일), 버튼2(이름,스타일)의 데이터를 받고,
각 버튼 눌렀을 때 어떤 메서드가 실행되는지.

이전에는 하나하나 모든 요소를 매개변수로 받았다. 위 모달에 파란색으로 표시되는 부분도 따로 받았었다.

리팩토링할 때 보니 충분히 간소화 할 수 있겠다고 생각하여 다음 코드를
Before

<div class="comments" v-html="comments1" v-if="comments1.length>0" ></div>
<div>
<span class="bluecomments" v-if="bluecomments.length>0">{{bluecomments}}</span> 
<span v-if="comments2.length>0"> {{comments2}} </span>
</div>  
  
<div style="display: flex;justify-content: center; width: 100%;">
  <img  v-if="sub_img" :src="sub_img"/>
</div>

After

<div class="comments" v-html="comments1" v-if="comments1.length>0" >  </div>
<div style="display: flex;justify-content: center; width: 100%;">
  <img  v-if="sub_img" :src="sub_img"/>
</div>

다음과 같이 간단해졌다.

  • 생각하지않고 코드를 짜다보니, 쉽게 할 수 있는 코드도 오히려 번거롭게 코드가 더 늘어나면서 가독성도 떨어지게 된 케이스의 대표적인 예시라고 생각한다.
    vue에서 v-html사용해서 바인딩하여 매개변수의 값에서도 html 태그를 사용할 수 있도록하여 태그에 스타일을 추가했습니다.

가독성을 위해 매개변수를 줄일 수는 없지만 수가 너무나도 많을때 어떻게해야 가독성이 올라갈까 고민을 하였는데, 나의 경우는 매개변수마다 숫자를 붙여 가독성과 어느정도의 효율성을 올렸다고 생각한다. (부모컴포넌트에서 필요한 매개변수만을 보내줄수 있도록)

    show: function(title_1, comments1_2,btn1_name_3,btn1_style_4,btn2_name_5,btn2_style_6,
    route_7,params_8,title_img_9,sub_img_10,callback_11) {
      this.show_it = true;  
      this.title = title_1;
      this.comments1 = comments1_2;
      this.btn1_name = btn1_name_3;
      this.btn1_style = btn1_style_4;
      this.btn2_name = btn2_name_5;
      this.btn2_style = btn2_style_6;
      this.title_img =title_img_9?  require(`../assets/${title_img_9}.png`) : ''
      this.sub_img =  sub_img_10?  require(`../assets/${sub_img_10}.png`): ''
      this.btn1_id = btn1_name_3;
      this.btn2_id = btn2_name_5;    

      this.route = route_7;         //route값에 http가 들어가면 새로운 브라우저 탭으로 연다.
      this.params = params_8        //리다이렉트 쿼리값으로 넘겨 로그인페이지의 경우 로그인후 리다이렉트 페이지로 보내준다.
      this.callback = callback_11;  //부모컴포넌트에서 필요한 메소드를 콜백함수로 받는다.(버튼클릭시 작동되게)
    },



//부모컴포넌트
 
 this.$refs.modal_popup.show('잠깐, 혜택을 포기하시나요?','지금 닫으면, 견적과 혜택이 사라질 수 있습니다.<br/>견적서룰 문자로 발송하여 내역을 저장하세요.<br/><span style="font-size:13px;">(혜택은 조기종료될 수 있습니다.)</span>',
'견적서로 돌아가기',style1,'닫기',style2,'quatation','','warning','quatation/hook_reward')

위와같이 모든 매개변수를 보낼때 몇번째자리인지 인지하고 있어야 왔다갔다 하지않고 코드를 잘 적을 수 있다.

버튼1또는 버튼2를 눌렀을때 모달창이 닫히는 기능은 기본이었고, 모달컴포넌트가 속한 부모컴포넌트에따라 버튼을 눌렀을시 라우팅이되거나 리다이렉션, 또는 부모컴포넌트의 함수를 사용해야하는 상황들이 많이 일어났다.
리팩토링 이전에는 버튼명에 따라 라우팅을 다르게 하는 방식을 채택했는데, 그럼 부모컴포넌트에 대한 의존성이 굉장히 올라가서 매 상황마다 코드가 추가되는 상황이 벌어진다.
그래서 매개변수에 함수를 넣어 보내고 버튼을 클릭시 함수가 실행되고,
버튼 이름이아닌 받는 매개변수에서 라우팅을 할 수 있도록 코드를 짰습니다.

Before

    signup_hide: function() {  //버튼 명에따라 라우팅하거나 다른 상황들을 매번 만들어야했다.
    if(this.btn2_name == '회원가입'||(this.query_value&&this.btn2_name == '회원가입')){ 
        if(this.redirect){
        const new_query = {redirect_name: this.redirect,purpose:'signup'}
        const update_query ={...this.query_value,...new_query}
        return  this.$router.push({name:this.route ,query:update_query})
        }else{
          return  this.$router.push({name:this.route ,query:this.query_value})
        }
      } if(this.route) {
      if(this.redirect){
      const new_query = {redirect_name: this.redirect}
      const update_query ={...this.query_value,...new_query}
      return  this.$router.push({name:this.route ,query:update_query})
      }else{
      return  this.$router.push({name:this.route ,query:this.query_value})
      }}
      if(this.title == '문자 발송 완료'){
      return this.show_it = false;
      } if(this.title == '온라인 계약신청 완료'){ 
      return  this.$router.push({name:'quatation'})
      } if(this.btn1_name =='견적서로돌아가기'){
      return  this.$router.push({name:'quatation'})
    } 
    if(this.title =='온라인 계약을 요청하시겠습니까?'){
      return this.$parent.push_data('online_request');
      }
     else return this.show_it = false;
    },
  
  }
  

after

 redirect_check: function() {  //매개변수 확인후 각 매개변수에 맞게 라우팅, 매개변수가 함수라면 함수 실행한다.
      const update_query = { ...this.query_value, ...this.params };

      if (this.route && this.params) {
        return this.$router.push({ name: this.route, query: update_query });
      }
      if(this.route && !this.params){
        return this.$router.push({ name: this.route });
      }
    },

    signup_hide: function() {
      if (typeof this.callback === 'function') {
        return this.callback();
      }
      this.redirect_check();
      this.show_it = false;
      }
  
  }

리팩토링후 코드가 약 40-50줄 줄었고, 가독성또한 좋아진게 보인다.

모듈화

  • global하게 어디에서나 사용할 수 있다
  • 어떤 특정한 상황에서도 의존성을 올리지 않는 방향으로 가야한다.
    (굳이 해야한다면, Data또는 함수를 받아둘 자리만 만들어주는 방향으로..)

리팩토링

  • 리팩토링 할 컴포넌트의 분석,다른 컴포넌트에 영향을 미친다면, 그 컴포넌트 또한 분석할 것 (JS, HTML, CSS(JS와연관되어있다면)
  • 기능이 중복되는가?
  • 숏코딩화 시켰지만 가독성이 올라가는가?
  • 기능적으로 더 빠른 실행속도를 올릴 방법이 있는가?

이번 리팩토링 작업으로 모듈화, 숏코딩과 가독성에 대해 실무에 있어 고민해보고 시도해보는 시간을 갖았는데, 리팩토링은 무조건 필요한 시간이라는 것, 기록과 회고에 대해 많은 관점이 바뀌게 되었다. 우리 모두 기록하고 성찰합시다 :)

profile
함께 일하고 싶어지는 동료가 되기를 원하는 프론트엔드 개발자입니다.

0개의 댓글