Last active
May 31, 2024 12:22
-
-
Save sunmeat/ec2194a8c89833d9a89ac8ed5f8fb426 to your computer and use it in GitHub Desktop.
weather C# example (pattern observer)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// подписчик | |
interface ISubscriber | |
{ | |
void Like(string content); | |
void Comment(string content); | |
void Message(string content); | |
void Ignore(string content); | |
void Unsubscribe(); | |
} | |
// издатель | |
abstract class Publisher | |
{ | |
protected List<ISubscriber> subscribers = new List<ISubscriber>(); | |
public void AddSubscriber(ISubscriber subscriber) | |
{ | |
subscribers.Add(subscriber); | |
} | |
public void RemoveSubscriber(ISubscriber subscriber) | |
{ | |
subscribers.Remove(subscriber); | |
} | |
public void NotifySubscribers(string content) | |
{ | |
var random = new Random(); | |
foreach (var subscriber in subscribers) | |
{ | |
int randomAction = random.Next(5); | |
if (randomAction == 0) subscriber.Like(content); | |
else if (randomAction == 1) subscriber.Comment(content); | |
else if (randomAction == 2) subscriber.Message(content); | |
else if (randomAction == 3) subscriber.Ignore(content); | |
else subscriber.Unsubscribe(); | |
} | |
} | |
} | |
class User : Publisher | |
{ | |
public void MakeStory(string content) | |
{ | |
Console.WriteLine("User made a story: " + content); | |
NotifySubscribers(content); | |
} | |
public void MakeReel(string content) | |
{ | |
Console.WriteLine("User made a reel: " + content); | |
NotifySubscribers(content); | |
} | |
public void PostPhoto(string content) | |
{ | |
Console.WriteLine("User posted a photo: " + content); | |
NotifySubscribers(content); | |
} | |
} | |
class InstagramFollower : ISubscriber | |
{ | |
public void Like(string content) | |
{ | |
Console.WriteLine("Like!"); | |
} | |
public void Comment(string content) | |
{ | |
Console.WriteLine("Comment!"); | |
} | |
public void Message(string content) | |
{ | |
Console.WriteLine("Sent a message!"); | |
} | |
public void Ignore(string content) | |
{ | |
Console.WriteLine("Ignored"); | |
} | |
public void Unsubscribe() | |
{ | |
Console.WriteLine("Unsubscribed from the user"); | |
} | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var Alex = new User(); | |
var Petya = new InstagramFollower(); | |
var Masha = new InstagramFollower(); | |
Alex.AddSubscriber(Petya); | |
Alex.AddSubscriber(Masha); | |
Alex.MakeStory("Beautiful sunset!"); | |
Alex.MakeReel("Fun dance!"); | |
Alex.PostPhoto("New profile picture!"); | |
} | |
} | |
// ============================================================================================= | |
using System; | |
using System.Collections; | |
using System.Net; | |
using System.Text.RegularExpressions; | |
using System.IO; | |
namespace ObserverPatternExample | |
{ | |
interface Observer // наблюдатель прогноза погоды (например, наше приложение) | |
{ // будет способен обновить у себя некоторые данные, причём сразу же, как только они обновятся на стороне источника | |
void Update(double temperature/*, double humidity, double pressure*/); | |
} | |
interface Subject // источник данных - может регистрировать подписчиков, удалять их из списка, уведомлять об изменениях | |
{ | |
void RegisterObserver(Observer observer); | |
void RemoveObserver(Observer observer); | |
void NotifyObservers(); | |
} | |
interface DisplayElement // выдача информации куда-либо (например, на экран консоли) | |
{ | |
void Display(); | |
} | |
class SinoptikWeatherData : Subject // конкретным источником данных будет сайт sinoptik.ua (можете по желанию переделать на gismeteo :)) | |
{ | |
ArrayList observers; // список всех подписчиков (это будут наши фанаты свежих новостей о погоде) | |
double temperature; // сайт будет предоставлять информацию по температуре воздуха | |
// double humidity; // влажность и давление можно добавить по желанию, суть не в этом :) | |
// double pressure; | |
public SinoptikWeatherData() | |
{ | |
observers = new ArrayList(); // изначально список пустой | |
} | |
public void RegisterObserver(Observer observer) | |
{ | |
observers.Add(observer); // добавляем в список нового "подписчика" | |
} | |
public void RemoveObserver(Observer observer) // при желании подписчика можно удалить из списка | |
{ | |
int index = observers.IndexOf(observer); | |
if (index >= 0) observers.RemoveAt(index); | |
} | |
public void NotifyObservers() // рассылаем уведомление о новой температуре всем подписчикам | |
{ | |
foreach (Observer ob in observers) | |
ob.Update(temperature/*, humidity, pressure*/); | |
} | |
private void MeasurementsChanged() // событие: температура изменилась, необходимо оповестить всех наблюдателей | |
{ | |
NotifyObservers(); | |
} | |
private void SetMeasurements(double temperature/*, double humidity, double pressure*/) | |
{ | |
this.temperature = temperature; | |
//this.humidity = humidity; | |
//this.pressure = pressure; | |
MeasurementsChanged(); | |
} | |
public void GetWeatherFromSinoptik(string city = "Черновцы") | |
{ | |
string url = "https://sinoptik.ua/погода-" + city; | |
WebRequest request; | |
request = WebRequest.Create(url); | |
using (var response = request.GetResponse()) | |
{ | |
using (var stream = response.GetResponseStream()) | |
using (var reader = new StreamReader(stream)) | |
{ | |
string data = reader.ReadToEnd(); | |
Regex r = new Regex("<p class=\"today-temp\">(?<temp>.*)"); | |
string result = r.Match(data).Groups["temp"].Value; | |
result = result.Remove(3); | |
// Console.WriteLine(result); // +27 | |
SetMeasurements(Convert.ToDouble(result)); | |
} | |
} | |
} | |
// конкретный наблюдатель - наше консольное приложение | |
class ConsoleApplication : Observer, DisplayElement | |
{ | |
double temperature; | |
// double humidity; | |
// double pressure; | |
Subject source; | |
public ConsoleApplication(Subject source) | |
{ | |
this.source = source; | |
this.source.RegisterObserver(this); | |
} | |
public void Update(double temperature/*, double humidity, double pressure*/) | |
{ | |
this.temperature = temperature; | |
// this.humidity = humidity; | |
// this.pressure = pressure; | |
Display(); | |
} | |
public void Display() | |
{ | |
Console.Write("Температура воздуха: "); | |
if (temperature > 0) Console.Write("+"); | |
Console.WriteLine(temperature + "°C"); | |
// Console.WriteLine("Влажность воздуха: " + humidity + "%"); | |
// Console.WriteLine("Давление: " + pressure + " мм рт.ст.\n"); | |
} | |
} | |
class Program | |
{ | |
public static void Main() | |
{ | |
Console.Title = "Observer"; | |
var weather = new SinoptikWeatherData(); | |
var app = new ConsoleApplication(weather); | |
weather.GetWeatherFromSinoptik("Черновцы"); | |
weather.GetWeatherFromSinoptik("Одесса"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment