Skip to content

Commit d33754b

Browse files
committed
Observer: improve conceptual example
1 parent d140f90 commit d33754b

File tree

2 files changed

+114
-54
lines changed

2 files changed

+114
-54
lines changed

Observer.Conceptual/Output.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@ Subject: Attached an observer.
22
Subject: Attached an observer.
33

44
Subject: I'm doing something important.
5-
Subject: My state has just changed to: 6
5+
Subject: My state has just changed to: 2
66
Subject: Notifying observers...
7+
ConcreteObserverA: Reacted to the event.
78
ConcreteObserverB: Reacted to the event.
89

910
Subject: I'm doing something important.
10-
Subject: My state has just changed to: 4
11+
Subject: My state has just changed to: 1
1112
Subject: Notifying observers...
12-
ConcreteObserverB: Reacted to the event.
13+
ConcreteObserverA: Reacted to the event.
1314
Subject: Detached an observer.
1415

1516
Subject: I'm doing something important.
16-
Subject: My state has just changed to: 8
17+
Subject: My state has just changed to: 5
1718
Subject: Notifying observers...

Observer.Conceptual/Program.cs

Lines changed: 109 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,154 @@
1-
using System;
1+
// EN: Observer Design Pattern
2+
//
3+
// Intent: Define a one-to-many dependency between objects so that when one
4+
// object changes state, all of its dependents are notified and updated
5+
// automatically.
6+
//
7+
// Note that there's a lot of different terms with similar meaning associated
8+
// with this pattern. Just remember that the Subject is also called the
9+
// Publisher and the Observer is often called the Subscriber and vice versa.
10+
// Also the verbs "observe", "listen" or "track" usually mean the same thing.
11+
//
12+
// RU: Паттерн Наблюдатель
13+
//
14+
// Назначение: Устанавливает между объектами зависимость «один ко многим» таким
15+
// образом, что когда изменяется состояние одного объекта, все зависимые от
16+
// него объекты оповещаются и обновляются автоматически.
17+
//
18+
// Обратите внимание, что существует множество различных терминов с похожими
19+
// значениями, связанных с этим паттерном. Просто помните, что Субъекта также
20+
// называют Издателем, а Наблюдателя часто называют Подписчиком и наоборот.
21+
// Также глаголы «наблюдать», «слушать» или «отслеживать» обычно означают одно
22+
// и то же.
23+
24+
using System;
225
using System.Collections.Generic;
326
using System.Threading;
427

528
namespace RefactoringGuru.DesignPatterns.Observer.Conceptual
629
{
730
public interface IObserver
831
{
9-
void update(ISubject subject);
32+
// EN: Receive update from subject
33+
//
34+
// RU: Получает обновление от издателя
35+
void Update(ISubject subject);
1036
}
1137

1238
public interface ISubject
1339
{
14-
void attach(IObserver observer);
15-
16-
void detach(IObserver observer);
17-
18-
void notify();
40+
// EN: Attach an observer to the subject.
41+
//
42+
// RU: Присоединяет наблюдателя к издателю.
43+
void Attach(IObserver observer);
44+
45+
// EN: Detach an observer from the subject.
46+
//
47+
// RU: Отсоединяет наблюдателя от издателя.
48+
void Detach(IObserver observer);
49+
50+
// EN: Notify all observers about an event.
51+
//
52+
// RU: Уведомляет всех наблюдателей о событии.
53+
void Notify();
1954
}
2055

56+
// EN: The Subject owns some important state and notifies observers when the
57+
// state changes.
58+
//
59+
// RU: Издатель владеет некоторым важным состоянием и оповещает наблюдателей о
60+
// его изменениях.
2161
public class Subject : ISubject
2262
{
63+
// EN: For the sake of simplicity, the Subject's state, essential
64+
// to all subscribers, is stored in this variable.
65+
//
66+
// RU: Для удобства в этой переменной хранится состояние Издателя,
67+
// необходимое всем подписчикам.
2368
public int State { get; set; } = -0;
2469

70+
// EN: List of subscribers. In real life, the list of subscribers
71+
// can be stored more comprehensively (categorized by event type, etc.).
72+
//
73+
// RU: Список подписчиков. В реальной жизни список подписчиков
74+
// может храниться в более подробном виде (классифицируется по типу события
75+
// и т.д.)
2576
private List<IObserver> _observers = new List<IObserver>();
2677

27-
public void attach(IObserver observer)
78+
// EN: The subscription management methods.
79+
//
80+
// RU: Методы управления подпиской.
81+
public void Attach(IObserver observer)
2882
{
29-
Console.Write("Subject: Attached an observer.\n");
83+
Console.WriteLine("Subject: Attached an observer.");
3084
this._observers.Add(observer);
3185
}
3286

33-
public void detach(IObserver observer)
87+
public void Detach(IObserver observer)
3488
{
35-
foreach (var elem in _observers)
36-
{
37-
if (elem == observer)
38-
{
39-
_observers.Remove(observer);
40-
Console.Write("Subject: Detached an observer.\n");
41-
break;
42-
}
43-
}
89+
this._observers.Remove(observer);
90+
Console.WriteLine("Subject: Detached an observer.");
4491
}
4592

46-
public void notify()
93+
//
94+
// EN: Trigger an update in each subscriber.
95+
//
96+
// RU: Запуск обновления в каждом подписчике.
97+
///
98+
public void Notify()
4799
{
48-
Console.Write("Subject: Notifying observers...\n");
100+
Console.WriteLine("Subject: Notifying observers...");
49101

50102
foreach (var observer in _observers)
51103
{
52-
observer.update(this);
104+
observer.Update(this);
53105
}
54106
}
55107

56-
public void someBusinessLogic()
108+
// EN: Usually, the subscription logic is only a fraction of what a Subject
109+
// can really do. Subjects commonly hold some important business logic, that
110+
// triggers a notification method whenever something important is about to
111+
// happen (or after it).
112+
//
113+
// RU: Обычно логика подписки – только часть того, что делает Издатель.
114+
// Издатели часто содержат некоторую важную бизнес-логику, которая запускает
115+
// метод уведомления всякий раз, когда должно произойти что-то важное (или
116+
// после этого).
117+
public void SomeBusinessLogic()
57118
{
58-
Console.Write("\nSubject: I'm doing something important.\n");
119+
Console.WriteLine("\nSubject: I'm doing something important.");
59120
this.State = new Random().Next(0, 10);
60121

61122
Thread.Sleep(15);
62123

63-
Console.Write("Subject: My state has just changed to: " + this.State + "\n");
64-
this.notify();
124+
Console.WriteLine("Subject: My state has just changed to: " + this.State);
125+
this.Notify();
65126
}
66127
}
67128

129+
// EN: Concrete Observers react to the updates issued by the Subject they had
130+
// been attached to.
131+
//
132+
// RU: Конкретные Наблюдатели реагируют на обновления, выпущенные Издателем, к
133+
// которому они прикреплены.
68134
class ConcreteObserverA : IObserver
69135
{
70-
public void update(ISubject subject)
71-
{
72-
if (!(subject is Subject))
73-
{
74-
return;
75-
}
76-
136+
public void Update(ISubject subject)
137+
{
77138
if ((subject as Subject).State < 3)
78139
{
79-
Console.Write("ConcreteObserverA: Reacted to the event.\n");
140+
Console.WriteLine("ConcreteObserverA: Reacted to the event.");
80141
}
81142
}
82143
}
83144

84145
class ConcreteObserverB : IObserver
85146
{
86-
public void update(ISubject subject)
147+
public void Update(ISubject subject)
87148
{
88-
if (!(subject is Subject))
89-
{
90-
return;
91-
}
92-
93149
if ((subject as Subject).State == 0 || (subject as Subject).State >= 2)
94150
{
95-
Console.Write("ConcreteObserverB: Reacted to the event.\n");
151+
Console.WriteLine("ConcreteObserverB: Reacted to the event.");
96152
}
97153
}
98154
}
@@ -101,19 +157,22 @@ class Client
101157
{
102158
public static void ClientCode()
103159
{
104-
var subj = new Subject();
105-
var o1 = new ConcreteObserverA();
106-
subj.attach(o1);
160+
// EN: The client code.
161+
//
162+
// RU: Клиентский код.
163+
var subject = new Subject();
164+
var observerA = new ConcreteObserverA();
165+
subject.Attach(observerA);
107166

108-
var o2 = new ConcreteObserverB();
109-
subj.attach(o2);
167+
var observerB = new ConcreteObserverB();
168+
subject.Attach(observerB);
110169

111-
subj.someBusinessLogic();
112-
subj.someBusinessLogic();
170+
subject.SomeBusinessLogic();
171+
subject.SomeBusinessLogic();
113172

114-
subj.detach(o2);
173+
subject.Detach(observerB);
115174

116-
subj.someBusinessLogic();
175+
subject.SomeBusinessLogic();
117176
}
118177
}
119178

0 commit comments

Comments
 (0)