본문 바로가기
Spring

[Spring] Spring Framework MVC 커뮤니티 사이트Tutorial - 4

by BENGGRI 2021. 2. 2.
반응형

 

1. 공통모듈

분석과 설계 과정을 진행하면서 다른 기능이지만 공통적으로 사용하는 기능이 눈에 보입니다.

물론 각 기능에서 공통적인 기능을 구현해 사용해도 되지만 공통적인 기능이 변경된다면 소스를 전체 수정해야합니다.

공통적으로 사용하는 기능을 따로 분리해 관리를 하는 것이 유리합니다.

 

해당 공통 기능이 동작하는 시점과 역할에 따라 어떤 방식으로 구현할지 고민해봐야합니다.

공통 기능들을 모아 class를 작성할 때 유의해야할 점이 있습니다.

이렇게 공통 기능들을 모아 작성한 class 를 공통 모듈이라 부릅니다.

 

1. 모듈 개념

  • 모듈은 크게 독립된 하나의 소프트웨어 또는 하드웨어 단위를 지칭하는 용어
  • 모듈화를 통해 분리된 시스템의 각 기능들을 서브프로그램, 서브 루틴, 소프트웨어 내의 단위 프로그램, 작업 단위 등과 같은 의미로 사용

2. 모듈의 특징

  • 각 모듈은 상대적으로 독립성을 가지고 있습니다.
  • 모듈 내부에는 그 모듈을 하나로 통합하는 수많은 조합이 존재할 수 있습니다.
  • 모듈은 단독으로 컴파일할 수 있으며 재사용할 수 있습니다.
  • 독립성이 높은 모듈일수록 수정 시 다른 모듈에 영향을 거의 미치지 않고 오류가 발생 시에도 쉽게 해결할 수 있습니다.

 

3. 결합도

  • 외부의 모듈과의 연관도
  • 상호의존성
  • 모듈 간의 관련성을 측정하는 척도
유형 설명 결합도 품질
내용 결합도 다른 모듈 내부에 있는 변수나 기능을 다른 모듈에서 사용하는 경우 높음 나쁨
공통 결합도 파라미터가 아닌 모듈 밖에 선언되어 있는 전역 변수를 참조하고 전역 변수를 갱신하는 식으로 상호작용하는 경우 | |
외부 결합도 두개의 모듈이 외부에서 도입된 데이터 포맷, 통신 프로토콜 또는 디바이스 인터페이스를 공유할 경우 | |
제어 결합도 단순 처리할 대상인 값만 전달되는 게 아니라 어떻게 처리를 해야한다는 제어 요소가 전달되는 경우 | |
스탬프 결합도 모듈 간의 인터페이스로 배열이나 객체, 구조 등이 전달되는 경우
자료 결합도 모듈 간의 인터페이스로 전달되는 파라미터를 통해서만 모듈간의 상호 작용이 일어나는 경우 낮음 좋음

 

4. 응집도

  • 모듈의 독립성
  • 모듈 내부 구성요소 간 연관 정도
유형 설명 응집도 품질
기능적 응집도 모듈 내부의 모든 기능이 단일한 목적을 위해 수행되는 경우 높음 좋음
순차적 응집도 모듈 내에서 한 활동으로부터 나온 출력값을 다른 활동이 사용할 경우 | |
통신적 응집도 동일한 입력과 출력을 사용하여 다른 기능을 수행하는 활동들이 모여있을 경우 | |
절차적 응집도 모듈이 다수의 관련 기능을 가질 때 모듈 안의 구성요소들이 그 기능을 순차적으로 수행할 때 | |
시간적 응집도 연관된 기능이라기보다 특정 시간에 처리되어야 하는 활동들을 한 모듈에서 처리할 경우 | |
논리적 응집도 유사한 성격을 갖거나 특정 형태로 분류되는 처리 요소들이 한 모듈에서 처리되는 경우
우연적 응집도 모듈 내부의 각 구성요소가 연관이 없을 경우 낮음 나쁨

 

5. 모듈의 독립성

결국 모듈의 독립성은 결합도와 응집도에 의해 측정됩니다.

독립성이 높은 모듈일 수록 모듈의 결합도는 낮게, 응집도는 높게 만들어야합니다.

 

쉽게 말해 수영복을 입고 수영을 하기 위해 수영장에 갔는데 축구를 하지 않아야 한다는 말입니다.

 

 

모듈의 독립성이 높을 수록 개발할 때 집중력이 좋습니다.


2. 공통 모듈 적용

공통 모듈을 구현하고 적용하게 되면 애플리케이션에서 공통적으로 사용하는 기능이나 중복 코드를 줄일 수 있습니다.

 

1. 공통 모듈 종류

종류 설명
업무 공통 업무에서 공통적으로 사용하는 기능으로 비즈니스를 포함한 기능
기능 공통 여러 시스템에서 공통으로 사용하는 비즈니스를 포함하고 있지 않은 기능

 

2. Util 

대표적으로는 StringUtil 이 있습니다.

( Spring 에서 제공하는 StringUtils [org.springframework.util Class StringUtils] )

 

필요에 따라 아래 함수를 포함한 Class를 만들어 사용할 수 있습니다.

  • null 이나 ""(빈값)을 파라미터로 전달받으면 기본값으로 리턴하는 함수
    (nulltoString, nvl ... 등)
  • Array((배열)이나 Date 등 여러 형태의 Object를 특정 형식의 문자열로 반환하는 함수
    (listToString, dateToString ... 등)
  • 좌우로 특정 문자열을 추가하거나 빈값을 제거하는 함수
    (padLeft, padRight, trimString, replaceString ... 등)

세부 로직에서 위 함수를 각각 구현하게 되면 중복코드많아지고 애플리케이션복잡해집니다.

그렇기 때문에 공통모듈로 구현하여 사용하는 것이 좋습니다.

 

경험했던 Util 의 목록 입니다.

Class 명 설명
StringUtil 문자 관련 Util
ExcelUtil 엑셀 파일 관련 Util
DateUtil 날짜 관련 Util
XMLUtil xml 관련 Util
EncryptionUtils 암호화 관련 Util
NumberUtil 숫자 관련 Util
PagingUtil 페이징 관련 Util
SessionUtil Session 관련 Util

 

3. Validation(유효성검사)

가장 자주 접하게 되는 데이터의 유효성 검사의 모습입니다.

Front(화면) 에서 사용자가 입력값을 입력하고 Back(서비스)에서 입력값을 전달받아 DB에 입력값을 저장합니다.

사용자가 입력한 입력값이 정해진 형식의 데이터인지 확인을 해야합니다.

  • 최대자리수 제한
  • 빈값허용여부
  • Null값허용여부
  • 형식체크
  • ... 등

사용자의 입력값만이 대상인 것은 아닙니다.

데이터의 유효성 검사는 애플리케이션 전체에서 발생하게 됩니다.

각 구간별 세부 로직에서 각각 구현하게 되면 코드 중복많아지고 애플리케이션복잡해집니다.

그렇기 때문에 별도의 모듈로 구현하여 사용하는 것이 좋습니다.

 

Front(화면), Back(서비스) 양 쪽에서 모두 유효성 검사를 해야합니다.

  1. Front(화면)에서 유효성 검사를 하더라도 악의적인 사용자가 해당 정보를 변경하여 Back(서비스)로 전달할 수 있고 때문입니다.
  2. Front(화면) 없이 API 를 이용해 Back(서비스)를 호출할 수 있기 때문입니다.
    (물론 허용하지 않은 API 는 사용할 수 없게 막아야합니다.)

 

4. 전처리/후처리

애플리케이션에서 기능을 실행하면 실행 전에 로그를 insert 하고 실행 후에 insert 한 로그를 update 한다거나 사전에 진행해야할 기능이 있을 수 있습니다.

세부 로직에서 각각 구현하게 되면 당연히 코드 중복많아지고 애플리케이션복잡해집니다.

이런 경우에도 별도의 모듈로 구현하여 사용하는 것이 좋습니다.

 

※ Spring 에는 AOP 가 있습니다.

 

 

5. 필요에 따라 추가, 삭제

작성한 항목보다 더 많이 필요할 수 있고 더 적게 필요할 수 있습니다.

(애플리케이션을 개발할 때 판단해야합니다.)

목표는 중복코드를 줄이고 애플리케이션을 덜 복잡하게 하는 것입니다.

 

 


3. 페이징 처리

개발을 처음 배웠을 때 페이징 처리에서 많이 어려웠습니다.

머리로는 이해가 되지만 손가락이 움직이지 않아서 였습니다.

 

한번에 5개의 공을 담을 수 있는 바구니가 있습니다.

공이 23개가 있으면 바구니는 몇개가 필요할까요?

총 23개의 공이 5개씩 바구니에 들어가야합니다.

4개의 바구니가 가득차고 3개는 남습니다.

그래서 총 4개가 아닌 5개의 바구니가 필요합니다.

 

머리로 페이징을 처리하는 방법은 이해가 됩니다.

 

전체 페이지 수를 구하는 방법은 아래와 같습니다.

int totCnt       = 23; // 전체 갯수
int bucketPerCnt = 5; // 한 바구니에 담을 수 있는 수
int bucketCnt    = 0; // 필요한 바구니 수

System.out.println( "totCnt/bucketPerCnt : "+totCnt/bucketPerCnt );
// totCnt/bucketPerCnt : 4
System.out.println( "totCnt%bucketPerCnt : "+totCnt%bucketPerCnt );
// totCnt%bucketPerCnt : 3
System.out.println( "bucketCnt : "+ (totCnt/bucketPerCnt+( (totCnt%bucketPerCnt)>0?1:0 )) );
// bucketCnt : 5
bucketCnt = (totCnt/bucketPerCnt+( (totCnt%bucketPerCnt)>0?1:0 ));

전체 갯수의 경우 DB에서 조회를 해와서 처리를 해야합니다.

/* 전체 갯수를 구하는 SQL문 */
SELECT COUNT(*)
FROM   TABLE

페이징에 필요한 정보는 전체 갯수, 한 바구니에 담을 갯수, 전체 바구니 갯수 입니다.

용어를 바꿔서 말하면 전체 데이터 갯수, 페이지 당 표시 갯수, 전체 페이지 갯수입니다.

전체 페이지를 처리하는 방법은 해결되었습니다.

 

게시판형 사이트를 보면 페이징은 아래 그림과 같은 형태로 표시 됩니다.

과 페이징을 표시하는 방법현재 페이지 목록 표시 방법입니다.

각 페이지의 시작과 끝 정보를 잘 보셔야합니다.

1페이지의 경우는 1 부터 5까지 입니다.

2페이지의 경우는 6 부터 10까지 입니다.

 

시작 번호부터 뒤로 5개의 정보를 조회하면 됩니다.

반대로 말하면 끝 번호 부터 앞으로 5개의 정보를 조회하면 됩니다.

 

끝 번호 = 페이지번호 X 표시할 갯수
1페이지 5 = 1 X 5
2페이지 10 = 2 X 5
3페이지 15 = 3 X 5
4페이지 20 = 4 X 5
5페이지 25 = 5 X 5
시작 번호 = 끝 번호 - 표시할 갯수 + 1
1 = 5 - 5 + 1
6 = 10 - 5 + 1
11 = 15 - 5 + 1
16 = 20 - 5 + 1
21 = 25 - 5 + 1

페이징 현재 페이지 목록을 처리 할 수 있습니다.


4. 중복체크

1. DB 조회

DB를 조회하는 중복체크는 회원가입의 아이디 입력에서 가장 많이 접할 수 있습니다.

보통 아이디를 입력하게 되면 즉시적으로 해당 아이디가 사용중인지 확인할 수 있습니다.

(중복체크 역시 Validation(유효성검사) 중 하나 입니다.)

사용자가 아이디를 입력하면 ajax 등을 이용해 입력값을 ID 중복체크를 하는 서비스로 입력값을 전달해 DB에 조회를 하고 난 뒤 결과를 화면에 출력할 수 있습니다.

사용자가 회원가입 버튼을 클릭하고 난 뒤에 화면에 표시할 수 있습니다.

두가지 방법 모두 Front(화면)에서 Back(서비스)를 호출해 DB의 정보를 조회해 중복을 체크할 수 있습니다.

 

2. 사용자 입력값 중복체크

사용자 입력값 중복체크는 SNS 나 게시글을 작성할 때 해시태그(#)에서 가장 많이 접할 수 있습니다.

위 그림처럼 사용자가 Spring 을 두번 입력한다고 가정했을 때 두번 째 Spring 은 입력되지 않도록 하는 것입니다.

사용자 입력값 정보를 담는 객체를 선언하고 이미 입력한 값일 경우 입력을 하지 않을 수 있습니다.

(물론 DB를 조회하는 방법도도 있습니다.)

 


5. 세션처리


# 화면 소스 템플릿

개인적으로 프로젝트를 만들 때는 템플릿을 주로 사용하게 됩니다.

(html 과 css 는 퍼블리싱이라는 전문 분야이기 때문입니다.)

 

현재 튜토리얼에서는 bootstrap 템플릿을 사용할 예정입니다.

 

다운로드한 압축파일 내부를 보시면 dashboard 예제가 앞으로 만들 프로젝트와 가장 비슷하게 구성되어있습니다.

dashboard 폴더 내 index.html 파일을 브라우저로 열어보시면 됩니다.

다운로드 파일 : 

bootstrap-5.0.0-beta1-examples.zip
1.28MB

반응형

댓글