Изначальная реализация паттерна проектирования "Наблюдатель" (Observer) для погоды
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace lb2
{
class Program
{
public static void Main()
{
WeatherData weatherData = new WeatherData();
CarrentConditionDisplay carrentDisplay = new CarrentConditionDisplay(weatherData);
//...
weatherData.setMeasurements(80, 65, 30.4);
weatherData.setMeasurements(82, 70, 29.2);
weatherData.setMeasurements(78, 90, 29.2);
Console.Read();
}
}
public interface Subject
{
public void registerObserver(Observer 0);
public void removeObserver(Observer 0);
public void notifyObservers();
}
public interface Observer
{
public void update(float temp, float hum, float press);
}
public interface DisplayElement
{
public void display();
}
public class WeatherData : Subject
{
// private string SubjectState { get; set; }
private ArrayList observers;
private float temp;
private float hum;
private float pressure;
public WeatherData()
{
observers = new ArrayList ();
}
public void registerObserver(Observer 0)
{
observers.Add(0);
}
public void removeObserver(Observer 0)
{
int i = observers.indexOF(0);
if (i>=0) observers.remove(i);
}
public void notifyObservers()
{
foreach (Observer obs in Observers)
Obs.opdate(temp, hum, pressure);
}
public void measurementsChanges()
{
notifyObservers();
}
public void SetMeasurements(float temp, float hum, float press);
{
this.temp = temp;
this.hum = hum;
this.pressure = press;
measurementsChanges();
}
//реализовать другие методы класса
public class CarrentConditionDisplay:Observer, DisplayElement
{
private float temper;
private float humid;
private Subject weatherData;
public CarrentConditionDisplay(Subject wData)
{
this.weatherData = wData;
wData.registerObserver(this);
}
public void update(float temp, float hum, float press)
{
this.temper = temp;
this.humid = hum;
Display();
}
public void Display()
{
System.Console.WriteLine("Текущие условия" + temper + "С и " + humid + "% влажности");
}
}
}
Очень много синтаксических ошибок. В интерфейсах нельзя использовать модификаторы (public, private и т.п.), на то он и интерфейс. На вход в методы передается ноль, надо переименовать. Классы не закрываются (нет символа '}' ). Значения float не завершаются буквой "f" в конце числа - писать 80f.
Нарушены соглашения: - локальные переменные объявляются как var; - приватные переменные начинаются либо со знака подчеркивания _ (далее слово начинается с маленькой буквы), либо с "m_", либо с "p_" (буквы m и p маленькие, после подчеркивания - начинается с большой); - интерфесы именуются с большой буквы "I"; - код плохо отформатирован.
Методы и свойства всегда начинаются с большой буквы (Pascal-нотация).
https://msdn.microsoft.com/ru-ru/library/ff926074.aspx
Рефакторинг. Этап 1
class Program
{
static void Main(string[] args)
{
var weatherData = new WeatherData();
CarrentConditionDisplay carrentDisplay = new CurrentConditionDisplay(weatherData);
weatherData.SetMeasurements(80f, 65f, 30f);
weatherData.SetMeasurements(82f, 70f, 29f);
weatherData.SetMeasurements(78f, 90f, 29f);
Console.Read();
}
}
public interface ISubject
{
void RegisterObserver(IObserver observer);
void RemoveObserver(IObserver observer);
void NotifyObservers();
}
public interface IObserver
{
void Update(float temp, float hum, float press);
}
public interface IDisplayElement
{
void Display();
}
public class WeatherData : ISubject
{
private readonly IList<IObserver> _observers = new List<IObserver>>();
private float _temp;
private float _hum;
private float _pressure;
public void RegisterObserver(IObserver observer)
{
_observers.Add(observer);
}
public void RemoveObserver(IObserver observer)
{
int i = _observers.IndexOf(observer);
if (i>=0) _observers.Remove(observer);
}
public void NotifyObservers()
{
foreach (var observer in _observers)
observer.Update(_temp, _hum, _pressure);
}
public void MeasurementsChanges()
{
NotifyObservers();
}
public void SetMeasurements(float temp, float hum, float press)
{
_temp = temp;
_hum = hum;
_pressure = press;
MeasurementsChanges();
}
//реализовать другие методы класса
}
public class CurrentConditionDisplay : IObserver, IDisplayElement
{
private float _temper;
private float _humid;
private ISubject _weatherData;
public CarrentConditionDisplay(ISubject wData)
{
_weatherData = wData;
wData.RegisterObserver(this);
}
public void Update(float temp, float hum, float press)
{
_temper = temp;
_humid = hum;
Display();
}
public void Display()
{
System.Console.WriteLine("Текущие условия: " + _temper + "С и " + _humid + "% влажности");
}
}
На самом деле Observer уже реализован в C# в виде событий. Ниже показано, как должен выглядеть код на C# в данном случае.
Рефакторинг. Этап 2
class Program
{
static void Main(string[] args)
{
var weatherData = new WeatherData();
weatherData.MeasurementsChanged += Display; //Подписались
weatherData.SetMeasurements(80f, 65f, 30f);
weatherData.SetMeasurements(82f, 70f, 29f);
weatherData.SetMeasurements(78f, 90f, 29f);
weatherData.MeasurementsChanged -= Display; //Отписались
Console.Read();
}
public static void Display(object sender, WeatherEventArgs e)
{
System.Console.WriteLine("Текущие условия: " + e.Temp + "С и " + e.Hum+ "% влажности");
}
}
public class WeatherEventArgs : EventArgs
{
public float Temp {get; set;}
public float Hum {get; set;}
public float Pressure {get;set;}
}
public class WeatherData
{
private float _temp;
private float _hum;
private float _pressure;
public event EventHandler<WeatherEventArgs> MeasurementsChanged;
protected virtual void OnMeasurementsChanges(WeatherEventArgs e)
{
var handler = MeasurementsChanged;
if (handler != null)
{
handler(this, e);
}
}
public void SetMeasurements(float temp, float hum, float press)
{
_temp = temp;
_hum = hum;
_pressure = press;
OnMeasurementsChanges(
new WeatherEventArgs { Temp = _temp, Hum = _hum, Pressure = _pressure } );
}
}
Элегантнее и короче, верно?

0 коммент.:
Отправить комментарий