본문 바로가기
TIL

[TIL] SRP(Single Responsibility Principle) 단일 책임 원칙

by 원동호 2021. 10. 5.
반응형
한 클래스는 단 한가지의 변경 이유만을 가져야한다.

톰 드마르코와 메이릴 페이지 존스의 연구에서 설명된것이다.

 

Laravel 디렉토리를 예로 살펴보자.

App 
	- Application의 핵심 코드를 담당한다.
BootStrap 
	- Laravel Framework의 부트스트래핑을 담당한다.
Config 
	- Application의 설정 파일을 담당한다.

각각의 디렉토리들은 각각의 책임을 맡고있다.

예를들어 Config 디렉토리가 App 디렉토리와 BootStrap 디렉토리를 책임지는 2가지의 책임을 맡고 있고

Config 디렉토리의 변경이 필요한 경우 디렉토리의 오동작을 유발 할 수도 있을것이다.

 

다음 Controller 코드를 살펴보자.

놀랍게도 과거 본인이 작성한 코드이다.

 

해당 Controller의 createUser메서드는 2가지의 책임으로 구성되어 있다.

  1. 유저가 입력한 정보를 바탕으로 유효성 검사
  2. 유저가 입력한 정보를 바탕으로 User 테이블에 데이터 삽입

실제 동작에는 문제가 없지만 유지보수 측면에서 문제점이 발생한다.

유저의 비밀번호 최솟값이 변경된다면? 유저 테이블에 컬럼이 추가된다면?

createUser메서드 뿐만 아니라 update 메서드도 필요하다면?

 

update할 경우 유저가 입력한 정보는 insert와 동일하기 때문에 유효성 검사 로직이 중복으로 작성될 것이며 컬럼 추가시 유효성 로직, User 데이터 삽입시 새로 추가된 컬럼도 추가로 작성해야 할것이다. 

class UsersController extends Controller {

	protected function createUser(Request $request) 
	{
	  $this->validate($request, [
	    'name' => 'required|max:255',
	    'email' => 'required|email|max:255|unique:users',
	    'password' => 'required|confirmed|min:6',
	    'tel' => 'nullable|digits_between:3,12',
	  ]);
	  
	  $confirmCode = str_random(60);
	  
	  $user = User::create([
	    'name' => $request->input('name'),
	    'email' => $request->input('email'),
	    'password' => bcrypt($request->input('password')),
	    'tel' => $request->input('tel'),
	  ]);
	  
		return redirect()->route('test');
	}
}

 

좀 더 나은 방법은?

 

  1. 유저가 입력한 정보를 Form Request를 이용하여 유효성 검사 로직을 진행한다.
  2. 서비스를 추가하여 유효성 검사가 완료된 값을 전달한다.

UserRequest , UserService Class를 추가하여 각각의 책임을 할당했다. 

  • Controller의 createUser 메서드는 유저의 요청을 받아 응답을 한다.
  • UserRequest Class는 유저가 입력한 정보를 바탕으로 유효성 검사 로직을 진행한다.
  • UserService는 유효성 검사가 완료된 값을 User 테이블에 저장한다.
# Controller
use App\Http\Requests\UserRequest;
class UsersController extends Controller {
	
	protected function createUser(UserRequest $request) 
	{
	 	$this->userService->post($request->all());
		return redirect()->route('user');
	}
}

# Form Request
use Illuminate\Foundation\Http\FormRequest;
class UserRequest extends FormRequest
{
    public function rules()
    {
        return [
          'name' => 'required|max:255',
          'email' => 'required|email|max:255|unique:users',
          'password' => 'required|confirmed|min:6',
          'tel' => 'nullable|digits_between:3,12',
        ];
    }
}

# Service
class UserService {
	public function post($user) {
		User::create([
		  'name' => $request->name,
		  'email' => $request->email,
		  'password' => bcrypt($request->password),
		  'tel' => $request->tel,
	  ]);
	}
}

 

 

 

반응형

댓글