Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Last active May 31, 2024 12:22
Show Gist options
  • Save sunmeat/ec2194a8c89833d9a89ac8ed5f8fb426 to your computer and use it in GitHub Desktop.
Save sunmeat/ec2194a8c89833d9a89ac8ed5f8fb426 to your computer and use it in GitHub Desktop.
weather C# example (pattern observer)
// подписчик
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