C++ 디자인 패턴 1. Strategy pattern(스트래티지 패턴), 2. Observer pattern(옵저버 패턴)

참고자료: Head First Design patterns


Strategy pattern(스트래티지 패턴)이란?


알고리즘군을 각각 캡슐화한다. 


그리고 각각의 알고리즘을 상황에 맞게 교환할 수 있도록 한다. 


알고리즘은 알고리즘을 사용하는 클라이언트의 코드변화 없이 사용이 가능하다.



2014/04/22 - [관심사/도서] - head first design patterns(객체지향 디자인 패턴) 서적(책)


주인공이 있고 주인공이 상황에 맞게 무기를 바꿔 사용하길 원합니다. 이럴 때 스트래티지 패턴이 유용합니다. 다음의 코드는 C++로 작성하였고 위 책을 참고했지만, 코드는 독립적입니다.  코드는 패턴의 형식을 이해하기 위한 최소의 형태로 만들었습니다. 자료는 최소한의 테스트 후 오류가 없는 자료를 올리지만, 생각지 못한 오류가 있을 수 있습니다.. 이 곳의 자료는 90% 창작이기 때문에 퍼가실 때는 댓글을 남겨주시고, 출처를 꼭 남겨주시기 바랍니다.


Strategy pattern(스트래티지 패턴)

Context또한 추상클래스로 구현할 수 있습니다. 이 때 Strategy *stg;를 protected로 해주시면 됩니다.

여기서 Strategy는 상황에 맞게 Strategy인터페이스를 구현한 클래스의 동작을 사용함을 말하는 것 같습니다.



Observer pattern(옵저버 패턴)이란?

객체간에 일대 다(One-to-Many)의 의존관계가 있다. 한 객체(One)의 상태변화는 의존관계에 있는 다른 객체들(Many)에게 알려지고 자동적으로 업데이트 된다.


Observer pattern(옵저버 패턴)


이 패턴은 간단할 것 같이 보이지만, 객체지향 디자인 패턴을 처음 접하는 저로서는 꽤 애먹은 패턴입니다. 아직 이해 안되는 부분이 있습니다. 

1. Subject를 인터페이스로 구현하지 않아도 될 듯 한데, 인터페이스로 구현하는 이유.(어짜피 Subject를 구현하는 클래스는 한개인데..)

생각할것 -> Subject를 구현하는 클래스는 여러 개가 될 수 있습니다. 일대 다라는 표현은 하나의 주제에 여러 개의 옵저버가 붙을 수 있다는 이야기입니다. Subect인터페이스 등록,삭제,알림 이 세가지 메소드는 어떤 주제가 되든 동일하기 때문에  Subect 인터페이스를 구현하면 이 형식을 꼭 구현해야 하기 때문에 통일성을 맞출 수 있습니다. 제가 느끼기에 여기서 Subject가 인스턴스에 대한 레퍼런스가 될 수는 없지만(만약 레퍼런스가 된다면, setStatus메소드를 호출할 때 에러가 난다) setStatus가 Subject에 순수 가상함수로 선언되어 있다면 해결되지만, 그렇게 하지 않는 이유는 아직 잘 모르겠네요.


이 디자인 패턴을 공부하면서 시야가 틔이는 부분도 있습니다.

Subject를 구현한 클래스에 Observer 클래스를 등록하는 방식입니다.

상식적으로 생각하면 Subject 내에서 등록 처리를 할 듯 보이지만, 정답은 반반입니다. Subject내에서는 등록에 대한 일반적인 처리를 하는 함수를 만든다면, Observer내에서 Subect의 인스턴스를 멤버변수로 만들고 객체 생성과 동시에 자신이 정보를 얻을 Subject객체를 인자로 받아들여 생성자에서 등록을 처리하는 부분입니다.

처음 생각은 등록 프로세스는 Subject내에 Observer 객체를 멤버변수로 만들고 등록 처리함수에 인자로 받아들이는 방식이기 때문에 Observer 객체를 생성한 후 Subject객체에서 등록 함수를 호출 하는 방식을 생각했습니다.

그런데 생성자에서 이 처리를 함으로서 등록 처리를 자동화 할 수 있게 되었네요.  소멸자내에서도 등록해제를 자동화 할 수 있지 않을까 생각합니다. 또한 인터페이스를 구현한 클래스들이기 때문에 소멸자들을 virtual로 해 주어야 합니다. 지금 보니 몇 가지 추가하고 고쳐야 할 부분이 있습니다. 자바의 경우는 이런 세세한 부분들 생각하지 않아도 제대로 작동하지만, C++은 꽤 생각해야 할 부분이 많다고 느끼네요. 특히 인터페이스를 구현할 때는 virtual 소멸자는 항상 생각해야 할 부분인 듯 합니다. 또한 여기서는 배열을 단순히 생성했지만, 실제 프로젝트라면 동적으로 생성해야 하겠죠.

이 댓글을 비밀 댓글로