Categories: Design Pattern

Behavioral Patterns – Observer

Observer – It lets the programs define a subscription mechanism to notify multiple objects, which means when the events happen, other objects can observe and immediately respond or modify object property.

From Design Pattern – Behavioral Patterns

Structure

Observer pattern – Class diagram UML

Applicability

  • Using its pattern when the programs change to the object state may require changing other objects, and the actual object sets are unknown beforehand or change dynamically.
  • Using its pattern when some objects must observe others in the program, but it is only for a limited time or in specific situations.

Pros and Cons

PROS

  • Open-closed principle – The developers can design the programs, which can introduce a new subscriber class without changing the publisher’s code and vice versa if there’s a publisher’s interface.
  • The programs can establish relations between objects at runtime.

CONS

  • Subscribers are notified in random order.
  • A large monolithic web application design architecture doesn’t scale well as new graphing or levied monolithic requirements.

How to Implement

#1 Basic Sample

static void Main(string[] args)
{
 var subject = new Subject();
 var ObserverA = new ConcreteObserver();
 subject.Attach(ObserverA);

 var ObserverB = new AnotherConcreteObserver();
 subject.Attach(ObserverB);

 subject.BusinessLogic();
 subject.BusinessLogic();
 
 subject.Detach(ObserverB);

 subject.BusinessLogic();

 Console.ReadKey();
}

public interface IObserver
{
 void Update(ISubject subject);
}

public interface ISubject
{
 void Attach(IObserver observer);
 void Detach(IObserver observer);
 void Notify();
}

public class Subject : ISubject
{
 public int State { get; set; } = -0;

 private List<IObserver> _observersList = new List<IObserver>();

 public void Attach(IObserver observer)
 {
  Console.WriteLine("Subject: Attached an object.");
  _observersList.Add(observer);
 }

 public void Detach(IObserver observer)
 {
  _observersList.Remove(observer);
  Console.WriteLine("Subject: Detached objects.");
 }

 public void Notify()
 {
  Console.WriteLine("Subject: Notifying observers.");

  foreach (var observer in _observersList)
   observer.Update(this);
 }

 public void BusinessLogic()
 {
  Console.WriteLine("\nSubject: Do something important.");
  State = new Random().Next(0, 10);

  Thread.Sleep(15);

  Console.WriteLine("Subject: My state has just changed to: " + State);
  Notify();
 }
}

public class ConcreteObserver : IObserver
{
 public void Update(ISubject subject)
 {
  if ((subject as Subject).State < 3)
   Console.WriteLine("Concrete Observer: Reacted to the event.");
 }
}

public class AnotherConcreteObserver : IObserver
{
 public void Update(ISubject subject)
 {
  if ((subject as Subject).State == 0 || (subject as Subject).State >= 2)
   Console.WriteLine("Another Concrete Observer: Reacted to the event.");
 }
}

#2 Web Application Project

Step 1 Create the interface and the service class files for the BLL. The interface class’ name sets “IObserverServices.” The service class’ name sets “ObserverServices.”

Fig 1 IObserverServices interface file source code.
Fig 2 ObserverServices class file source code.

Step 2 Create the observer interface class files, which name sets “IObserver.” Create the concrete observer class file, which name sets “ConcreteObserver.”

Fig 3 IObserver interface file source code.
Fig 4 ConcreteObserver class file source code.

Step 3 Create the subject interface class files. This class file’s name sets “ISubject.” Create the concrete subject class file which name sets “Subject.” In this sample, I create another class file that inherits the subject class file, which lets the concrete subject class object can a more extended application.

Fig 5 ISubject class file source code.
Fig 6 Subject class file source code.

Step 4 Create the observer-related files, such as the controller part files, the view part files, etc.

Step 5 Register the Core’ project observer-related files in the web project’ startup.cs files.

// Observer
services.AddScoped(typeof(IObserverServices), typeof(ObserverServices));
Fig 7 Observer result.

Reference

davidsky69

View Comments

Recent Posts

API Gateway in .NET 5 with Ocelot

What is the API gateway? An API gateway is an API management tool that sits…

4 years ago

.NET 5 application with Onion architecture

The .NET 5 SDK is a kind of milestone in the .NET world. The .NET…

4 years ago

SOLID Principles – Dependency inversion principle

In object-oriented design, the dependency inversion principle is a specific methodology for loosely coupling software…

4 years ago

SOLID Principles – Interface segregation principle

In the field of software engineering, the interface segregation principle (ISP) states that no code…

4 years ago

SOLID Principles – Liskov substitution principle

Subtype Requirement: Let  be a property provable about objects  of type T. Then  should be true for objects  of type S where S is…

4 years ago

SOLID Principles – Open-closed principle

In object-oriented programming, the open–closed principle states "software entities (classes, modules, functions, etc.) should be…

4 years ago