2009-04-29 2 views
4

두 가지 클래스가 있습니다 : 계정 및 운영자. 계정에 운영자 목록이 포함되어 있습니다. 이제 연산자 (목록에있는)가 메시지를 수신 할 때마다 Account 개체에 비즈니스 논리를 수행하도록 알리고 싶습니다.컨테이너 개체 알리기 : 모범 사례

1) 컨테이너 [계정] 객체에 대한 운영자 내에서 참조를 잡고 직접 메소드를 호출 :

나는 이것을 달성하는 방법에 대한 세 가지 대안을 생각한다. 순환 참조 때문에 절대적으로 좋지 않습니다.

2) 이벤트 사용. 내가 아는 한, 파이썬에는 내장 이벤트 처리 메커니즘이 없다. 그래서, 이것은 구현하기에 약간 까다 롭습니다.

3) 운영자에게 직접 메시지를 보내지 마십시오. 대신 계정 만 작동하고 내부적으로는 처리기 운영자를 사용하십시오. 이것은이 경우에는 연산자에 대한 참조를 전달할 수 없기 때문에 약간 제한적입니다.

어떤 접근 방식이 아키텍처 관점에서 가장 유리한 지 궁금합니다. 이 작업을 어떻게 처리합니까?

파이썬에서 스 니펫을 지적 할 수 있다면 좋을 것입니다.

답변

5

당신은 이것을 과장 생각하고 있습니다. 진지하게. 파이썬은 C++이 아닙니다. 귀하의 우려는 Python의 비공식 문제입니다. 문제 도메인에서 의미가있는 것을 작성하십시오.

"순환 참조 때문에 절대적으로 좋지 않습니다."

왜 안 되니? 원형은 전혀 관련이 없습니다. 양방향 관계는 훌륭한 것입니다. 그것을 써. 파이썬 쓰레기는 여러분의 생각을 전혀하지 않고 잘 수집합니다.

상호 (양방향) 관계에서 발생할 수있는 문제점은 무엇입니까?

"... 계정과 내부적으로는 내부적으로 처리기 연산자가 있습니다.이 경우에는 연산자에 대한 참조를 전달할 수 없기 때문에 약간 제한이 있습니다. "

무엇? 귀하의 운영자는 당신이 원하는 모든를 전달합니다. 모든 파이썬 객체는 참조 (효과), 걱정하지 않는다있다. 당신이 운영자 객체를 조작하여이 있습니까 가능한 어떤 문제

을 파이썬 객체인가? 당신이 인스턴스 메서드에 대해 알고하지 않을 수 있습니다

+0

+1 - Python 2.5를 사용하고 __del__ 메소드를 정의하지 않는 한 순환 참조는 크지 않습니다. 더 이상 거래하지 마라. –

+1

@ Jason Baker : Python을 7 년 동안 많이 사용해 왔지만 __del__ 메소드를 정의하지 않았습니다. 양방향 관계에 문제가 없었으므로 정기적으로 사용하십시오. 그들은 2.2까지 줄곧 위대한 일을했습니다. –

+0

좋아, 모든 순환 참조를 추적한다는 것을 몰랐다. 하지만 __del__ 메서드를 정의하면 (어떤 이유로 든) 어떻게 될까요? 나는 아직도 그들을 수동으로 추적해야한다, 그렇지? –

3

Observer 패턴을위한 "one-size-fits-all"솔루션은 없습니다. 그러나 일반적으로 이해 관계자가 특정 이벤트에 대해 자신을 등록하고 발생할 때마다 이벤트를 게시 할 수있는 EventManager 객체를 정의하는 것이 좋습니다. 단순히 의존성을 덜 만듭니다.

전역 이벤트 관리자 인스턴스를 사용해야합니다. 테스트 중에 또는 일반적인 OO 관점에서 문제가 될 수 있습니다 (전역 변수). EventManager를 항상 통과시키지 말 것을 강력히 권합니다. 코드가 복잡해지기 때문입니다.

내 자신의 코드에서 이벤트 등록을위한 "키"는 이벤트 클래스입니다. EventManager는 사전 (이벤트 클래스 -> 옵저버 목록)을 사용하여 어떤 이벤트가 어디로 가는지 알 수 있습니다. 알림 코드에서 dict.get(event.__class__,())을 사용하여 리스너를 찾을 수 있습니다.

+0

감사 : 신뢰할 수있는 코드의 좋은 소스는 활성 상태, 예컨대입니다. –

3

이 경우 이벤트 처리를 사용합니다. 당신은 직접 구현할 필요가 없습니다 - 정확히 이런 종류의 이벤트 처리에 pydispatcher을 사용합니다. 그리고 순환 참조 문제를 피하기 위해 내부적으로 약한 참조를 사용합니다.

또한 gui 프레임 워크를 사용하는 경우 이미 연결할 수있는 이벤트 프레임 워크가있을 수 있습니다. 예를 들어 PyQt에는 신호와 슬롯이 있습니다.

+0

+1에 대한 pydispatcher 및 그 친족. 사용이 간편하며 설명 된 상황을 정확히 해결할 수 있도록 설계되었습니다. 그것은 필요한 경우 다른 컨테이너 안에 연산자를 연결할 수있는 방식으로 객체를 분리합니다. –

3
>>> class Account(object): 
...  def notify(self): 
...   print "Account notified" 
... 
>>> class Operator(object): 
...  def __init__(self, notifier): 
...   self.notifier = notifier 
... 
>>> A = Account() 
>>> O = Operator(A.notify) 
>>> O.notifier() 
Account notified 
>>> import gc 
>>> gc.garbage 
[] 
>>> del A 
>>> del O 
>>> gc.garbage 
[] 

한 가지 도트 구문을 사용할 때 고개를 때 바인드하고 있다는 점이다. A.notify 말을 다른 말로하면 자동으로 다음 저장할 수있는 A로 통지의 자기 매개 변수를 결합 회수 할 수없는 쓰레기를 만들지 않고이 기능에 대한 참조.

마지막으로 언제든지 Kamaelia을 사용할 수 있습니다.

+0

와우, 코드 스 니펫과 매우 명확한 설명에 감사드립니다. 매우 흥미로운 접근법. –