C\#디자인 모델 시리즈 튜 토리 얼-관찰자 모드
때로는 게시/구독 모드 라 고 불 리 며 관찰자 모드 는 한 쌍 의 다 중 의존 관 계 를 정의 하여 여러 관찰자 대상 이 특정한 주제 대상 을 동시에 감청 하도록 한다.이 테마 대상 은 상태 가 변 할 때 모든 관찰자 대상 에 게 자동 으로 자신 을 업데이트 할 수 있 도록 알려 줍 니 다.
2.해결 하 는 문제
하나의 시스템 을 서로 협력 하 는 유형 으로 나 누 는 것 은 좋 지 않 은 부작용 이 있다.그것 은 바로 관련 대상 간 의 일치 성 을 유지 해 야 한 다 는 것 이다.우 리 는 일치 성 을 유지 하기 위해 각종 긴밀 한 결합 을 원 하지 않 는 다.이렇게 하면 유지,확장 과 재 활용 에 불편 을 가 져 올 수 있다.관찰 자 는 바로 이런 결합 관 계 를 해결 하 는 것 이다.
3.모드 속 캐릭터
3.1 추상 적 인 주제(Subject):모든 관찰자 대상 의 인용 을 하나의 집합 에 저장 하고 모든 주 제 는 모든 수량의 관찰자 가 있 을 수 있다.추상 적 인 테 마 는 관찰자 대상 을 추가 하고 삭제 할 수 있 는 인 터 페 이 스 를 제공 합 니 다.
3.2 구체 적 인 주제(Concrete Subject):관련 상 태 를 구체 적 인 관찰자 대상 에 저장 합 니 다.구체 적 인 주제 내부 상태 가 바 뀌 었 을 때 등 록 된 모든 관찰자 에 게 알림 을 보 냅 니 다.
3.3 추상 적 인 관찰자(Observer):모든 구체 적 인 관찰자 에 게 인 터 페 이 스 를 정의 하고 주제 알림 을 받 을 때 자신 을 업데이트 합 니 다.
3.4 구체 적 인 관찰자(ConcreteObserver):추상 적 인 관찰자 역할 이 요구 하 는 업데이트 인 터 페 이 스 를 실현 하여 자신의 상태 와 주제 상 태 를 조 화 롭 게 한다.
4.패턴 판독
4.1 관찰자 모델 의 유형 도
4.2 관찰자 모드 의 코드
/// <summary>
///
/// </summary>
public abstract class Subject
{
private IList<Observer> observers = new List<Observer>();
/// <summary>
///
/// </summary>
/// <param name="observer"></param>
public void Attach(Observer observer)
{
observers.Add(observer);
}
/// <summary>
///
/// </summary>
/// <param name="observer"></param>
public void Detach(Observer observer)
{
observers.Remove(observer);
}
/// <summary>
/// ( )
/// </summary>
public void Notify()
{
foreach (Observer o in observers)
{
o.Update();
}
}
}
/// <summary>
/// , ,
/// </summary>
public abstract class Observer
{
public abstract void Update();
}
/// <summary>
/// , ; , 。 。
/// </summary>
public class ConcreteSubject : Subject
{
private string subjectState;
/// <summary>
///
/// </summary>
public string SubjectState
{
get { return subjectState; }
set { subjectState = value; }
}
}
/// <summary>
/// , ,
/// </summary>
public class ConcreteObserver : Observer
{
private string observerState;
private string name;
private ConcreteSubject subject;
/// <summary>
///
/// </summary>
public ConcreteSubject Subject
{
get { return subject; }
set { subject = value; }
}
public ConcreteObserver(ConcreteSubject subject, string name)
{
this.subject = subject;
this.name = name;
}
/// <summary>
///
/// </summary>
public override void Update()
{
observerState = subject.SubjectState;
Console.WriteLine("The observer's state of {0} is {1}", name, observerState);
}
}
4.3 클 라 이언 트 코드
class Program
{
static void Main(string[] args)
{
//
ConcreteSubject subject = new ConcreteSubject();
subject.Attach(new ConcreteObserver(subject, "Observer A"));
subject.Attach(new ConcreteObserver(subject, "Observer B"));
subject.Attach(new ConcreteObserver(subject, "Observer C"));
subject.SubjectState = "Ready";
subject.Notify();
Console.Read();
}
}
실행 결과5.모델 총화
5.1 장점
5.1.1 관찰자 모델 은 주제 와 구체 적 인 관찰자 의 결합 을 해제 하고 결합 하 는 쌍방 이 구체 적 인 것 에 의존 하 는 것 이 아니 라 추상 에 의존 하도록 한다.그래서 각자 의 변 화 는 다른 쪽 의 변화 에 영향 을 주지 않 는 다.
5.2 단점
5.2.1 의존 관 계 는 완전히 해제 되 지 않 았 고 추상 적 인 통지 자 는 추상 적 인 관찰자 에 게 의존 했다.
5.3 필드 적용
5.3.1 한 대상 의 변화 가 다른 대상 에 게 주어 야 할 때 구체 적 으로 몇 개의 대상 이 바 뀌 어야 할 지 모른다.
5.3.2 하나의 추상 적 인 특정한 유형 은 두 가지 측면 이 있 는데 그 중의 한 가지 측면 이 다른 측면 에 의존 할 때 관찰자 모델 로 이 두 가 지 를 독립 된 대상 에 포장 하여 각자 독립 적 으로 변화 시 키 고 재 활용 할 수 있다.
6.모드 설명,C\#의 이벤트 의뢰 를 사용 하여 알림 자 와 관찰자 간 의 결합 을 철저히 해제 합 니 다.
6.1 의뢰 에 대한 정의:의뢰 는 인용 방법의 유형 이다.일단 위탁 을 위해 방법 을 분배 하면 위탁 은 이 방법 과 같은 행 위 를 할 것 이다.위탁 방법 은 다른 어떤 방법 과 마찬가지 로 매개 변수 와 반환 값 을 가 질 수 있다.의뢰 는 함수(방법)에 대한 추상 적 이 고 함수 의'클래스'로 볼 수 있 으 며 의뢰 의 인 스 턴 스 는 하나의(또는 여러 개)구체 적 인 함 수 를 대표 하 며 다 중 방송 할 수 있 습 니 다.
6.2 사건:사건 은 의뢰 를 바탕 으로 의뢰 에 발표/구독 체 제 를 제공 합 니 다.이벤트 의 구독 과 취 소 는 우리 가 방금 말 한 관찰자 모드 의 구독 과 취소 와 유사 하지만 표현 형식 만 다르다.관찰자 모드 에서 구독 사용 방법 Attach()로 진행 합 니 다.이벤트 구독 에'+='을 사용 합 니 다.이와 유사 하 게 구독 취 소 는 관찰자 모드 에서 Dettach()를 사용 하고 이벤트 취 소 는'-='을 사용한다.
7.다음 의 예 는 관찰자 모델,사건 체제 로 이 루어 진다.
7.1 사례 설명:고객 이 주문 금액 을 지불 했다.이때 재 무 는 영수증 을 발급 해 야 하고 출납 은 기장 해 야 하 며 배 송 원 은 배 송 해 야 한다.
7.2 관찰자 모델 의 실현
7.2.1 도표
7.2.2 코드 구현
/// <summary>
///
/// </summary>
public interface ISubject
{
void Notify();
}
/// <summary>
/// ,
/// </summary>
public abstract class JobStation
{
public abstract void Update();
}
/// <summary>
/// ,
/// </summary>
public class Customer : ISubject
{
private string customerState;
private IList<JobStation> observers = new List<JobStation>();
/// <summary>
///
/// </summary>
/// <param name="observer"></param>
public void Attach(JobStation observer)
{
this.observers.Add(observer);
}
/// <summary>
///
/// </summary>
/// <param name="observer"></param>
public void Detach(JobStation observer)
{
this.observers.Remove(observer);
}
/// <summary>
///
/// </summary>
public string CustomerState
{
get { return customerState; }
set { customerState = value; }
}
public void Notify()
{
foreach (JobStation o in observers)
{
o.Update();
}
}
}
/// <summary>
///
/// </summary>
public class Accountant : JobStation
{
private string accountantState;
private Customer customer;
public Accountant(Customer customer)
{
this.customer = customer;
}
/// <summary>
///
/// </summary>
public override void Update()
{
if (customer.CustomerState == " ")
{
Console.WriteLine(" , 。");
accountantState = " ";
}
}
}
/// <summary>
///
/// </summary>
public class Cashier : JobStation
{
private string cashierState;
private Customer customer;
public Cashier(Customer customer)
{
this.customer = customer;
}
public override void Update()
{
if (customer.CustomerState == " ")
{
Console.WriteLine(" , 。");
cashierState = " ";
}
}
}
/// <summary>
///
/// </summary>
public class Dilliveryman : JobStation
{
private string dillivierymanState;
private Customer customer;
public Dilliveryman(Customer customer)
{
this.customer = customer;
}
public override void Update()
{
if (customer.CustomerState == " ")
{
Console.WriteLine(" , 。");
dillivierymanState = " ";
}
}
}
7.2.3 클 라 이언 트 코드
class Program
{
static void Main(string[] args)
{
Customer subject = new Customer();
subject.Attach(new Accountant(subject));
subject.Attach(new Cashier(subject));
subject.Attach(new Dilliveryman(subject));
subject.CustomerState = " ";
subject.Notify();
Console.Read();
}
}
실행 결과:저 는 회계 입 니 다.영수증 을 발급 하 겠 습 니 다.
저 는 출납원 입 니 다.등록 해 드 리 겠 습 니 다.
배 송 원 입 니 다.배 송 하 러 왔 습 니 다.
7.3 사건 실현
7.3.1 도표
아 날로 그 를 통 해 볼 때 관찰자 와 주제 사이 에는 이미 어떠한 의존 관계 도 존재 하지 않 는 다.
7.3.2 코드 구현
/// <summary>
///
/// </summary>
public interface ISubject
{
void Notify();
}
/// <summary>
///
/// </summary>
public delegate void CustomerEventHandler();
/// <summary>
///
/// </summary>
public class Customer : ISubject
{
private string customerState;
// , CustomerEventHandler
public event CustomerEventHandler Update;
public void Notify()
{
if (Update != null)
{
//
Update();
}
}
public string CustomerState
{
get { return customerState; }
set { customerState = value; }
}
}
/// <summary>
/// , ,
/// </summary>
public class Accountant
{
private string accountantState;
public Accountant()
{ }
/// <summary>
///
/// </summary>
public void GiveInvoice()
{
Console.WriteLine(" , 。");
accountantState = " ";
}
}
/// <summary>
/// , ,
/// </summary>
public class Cashier
{
private string cashierState;
public void Recoded()
{
Console.WriteLine(" , 。");
cashierState = " ";
}
}
/// <summary>
/// , ,
/// </summary>
public class Dilliveryman
{
private string dillivierymanState;
public void Dilliver()
{
Console.WriteLine(" , 。");
dillivierymanState = " ";
}
}
7.3.3 클 라 이언 트 코드
class Program
{
static void Main(string[] args)
{
Customer subject = new Customer();
Accountant accountant = new Accountant();
Cashier cashier = new Cashier();
Dilliveryman dilliveryman = new Dilliveryman();
//
subject.Update += accountant.GiveInvoice;
subject.Update += cashier.Recoded;
subject.Update += dilliveryman.Dilliver;
/*
*
subject.Update += new CustomerEventHandler(accountant.GiveInvoice);
subject.Update += new CustomerEventHandler(cashier.Recoded);
subject.Update += new CustomerEventHandler(dilliveryman.Dilliver);
*/
subject.CustomerState = " ";
subject.Notify();
Console.Read();
}
}
실행 결과저 는 회계 입 니 다.영수증 을 발급 하 겠 습 니 다.
저 는 출납원 입 니 다.등록 해 드 리 겠 습 니 다.
배 송 원 입 니 다.배 송 하 러 왔 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
WebView2를 Visual Studio 2017 Express에서 사용할 수 있을 때까지Evergreen .Net Framework SDK 4.8 VisualStudio2017에서 NuGet을 사용하기 때문에 패키지 관리 방법을 packages.config 대신 PackageReference를 사용해야...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.