Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Observer Pattern 이란


옵서버 패턴(observer pattern)은 객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 디자인 패턴이다. 주로 분산 이벤트 핸들링 시스템을 구현하는 데 사용된다. 발행/구독 모델로 알려져 있기도 하다. - 출처 wikipedia

옵저버 패턴은 객체의 상태 변화를 등록한 관찰자에게 알려주는 패턴으로 데이터 변경이 발생할 때 여러 객체에게 통지할 수 있습니다.

...

개별 모델 클래스에 처리하려는 이벤트 이름의 메서드를 작성하고 boot() 에 등록해 주면 됩니다. 예로 포스트 작성시 글쓴이의 id(writer_id 필드) 를 자동으로 설정하려면 아래와 같이 boot() 메서드에 creating() 을 구현해 주면 됩니다.

Code Block
languagephp
titlemodel class
class Post
{
    protected static function boot()
    {
        parent::boot();

		// post 생성시 글쓴 이의 user_id 로 설정
        static::creating(function ($model) {
            $model->writer_id = \Auth::user()->id;
        });
    }

...

DBMS 의 foreign key 를 사용해서 Comment 모델이 Post 모델을 참조하게 했을 경우 cascading option 이 옵션을 주지 않았다면 DBMS 차원에서 삭제가 불가능합니다.


하지만 이런 경우 다음과 같은 DBMS 차원의 에러가 발생하므로 삭제를 수행한 사용자는 원인이 무엇인지 혼란스러워 할 수 있습니다.

Code Block
Illuminate/Database/QueryException with message 'SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails 



그래서 삭제전에 댓글이 있는지 확인해서 사용자가 인지할 수 있는 에러 메시지를 전달하는 게 좋습니다.

옵저버 클래스에 deleteddeleting() 메서드를 아래와 같이 구현하면 사용자는 댓글있는 게시글 삭제시 이해할 수 있는 에러 메시지를 만날 수 있습니다.

Code Block
class PostObserver
{
  /**
     * Handle the post "deleteddeleting" event.
     *
     * @param  \App\Post  $post
     * @return void
     */
    public function deleteddeleting(Post $post)
    {
		$count = $post->comments()->count();
        
		if ($count > 0) 
		{
			throw new ExceptionDataIntegrityException("댓글이 달려있는 게시글은 삭제할 수 없습니다.");
		}
		
		$user = \Auth::user();
		
		if ($user->id != $post_writer_id)
		{
			throw new ExceptionNotPermittedException("본인이 작성한 게시글만 삭제할 수 있습니다.");
		}
    }

...