Как Вы были бы Вы описывать шаблон The Observer на языке новичка?

Вы могли бы сделать это, но, вероятно, есть гораздо лучший способ

$($('.placeholderbokehapp').css('height', '1700px'))
14
задан Bill the Lizard 15 September 2012 в 23:12
поделиться

16 ответов

Лучший пример, который я могу привести, - это список рассылки (в качестве примера).

Вы , обозреватель, подпишитесь на список рассылки, и вы наблюдаете список. Когда вас больше не интересует список, вы отписываетесь.

Эта концепция является моделью наблюдателя. Два или более классов участвуют. Один или несколько классов подписываются на класс издателя (существуют разные имена), а затем первый класс (и каждый подписывающийся класс) получит уведомление, когда этого пожелает издатель.

Вот как я объяснил это своей жене, которая часто слушает мои разговоры о программировании и теории дизайна. Это имело смысл для нее. Я понимаю, что это может быть слишком просто для вас, но это хорошее начало ...

С уважением,
Франк

27
ответ дан 1 December 2019 в 06:48
поделиться

В одном предложении:

Объект (субъект) позволяет другим объектам (наблюдателям) подписываться на уведомления ,

Практический пример:

Допустим, у вас есть приложение, и вы хотите позволить другим разработчикам создавать плагины.

Вы можете создать класс PluginSubject и поместить в него метод с именем NotifyOrderCreated. Всякий раз, когда на экране заказа создается новый заказ, он вызывает PluginSubject.NotifyOrderCreated.

Когда это происходит, PluginSubject получает список PluginObservers и вызывает PluginObserver.Notify для каждого из них, передавая сообщение, описывающее событие.

Это обеспечивает действительно полезную функциональность.

Это гораздо больше, чем вы хотите знать:

Я действительно делал это недавно, поэтому я возьму пример еще на шаг глубже - если вам потребуется, чтобы ваши наблюдатели реализовали специальный интерфейс, позвольте ' Скажем, IPluginObserver, вы можете использовать отражение для обхода типов в вашей сборке и создания плагинов на лету.

Затем вы можете позволить пользователям подписывать свои собственные сборки (вам нужно где-то сохранить список имен сборок, а затем пройтись по нему), и bam, у вас есть расширяемость!

0
ответ дан 1 December 2019 в 06:48
поделиться

Наблюдатель - это средство разъединения, то есть ослабления связей между двумя объектами. Вы хотите этого, потому что это делает ваш код аккуратнее и проще в обслуживании. Это в значительной степени цель всех шаблонов проектирования: легче читать, легче поддерживать код.

В этом шаблоне у вас есть два класса, два объекта: издатель и обозреватель. Publisher - это класс, который на самом деле выполняет некоторую работу, затем он часто вызывает методы у любых наблюдателей, чтобы сообщить им об этом. Он знает, какие классы вызывать, потому что он хранит список наблюдателей, которые подписались.

Таким образом, ваш издатель может выглядеть примерно так:

class Publisher
{
    List<Observer> observers = new List<Observer>();

public Add(Observer o)
{
    observers.Add(o);
}

private AlertObservers()
{
    foreach(Observer o in observers)
    {
        o.Alert();
    }
}

Издатель действительно выполняет большую часть работы. Все, что нужно сделать Наблюдателю, - это добавить его в список и реализовать вызываемый метод. Примерно так:

class Observer
{
    public Observer(Publisher pub)
    {
        pub.Add(this);
    }

    public Alert()
    {
        System.Console.WriteLine("Oh no, stuff is happening!");
    }
}

Это довольно скромное представление о том, как это работает. Сейчас же, почему это ценно? Выглядит довольно хорошо, да? Одна из причин этого заключается в том, что я не использую интерфейс, который позволил бы мне настроить многие классы с функциональностью Observer, и Publisher никогда не нужно знать о них больше ничего, кроме того, что они могут получать вызов Alert (). Также обратите внимание, что Publisher будет пытаться вызвать Alert для любого и всех Наблюдателей, которые у него есть, даже если у него их нет.

Теперь, в мире C #, язык имеет встроенную версию этого шаблона через его объекты Event. События очень мощные и используют делегатов, что является способом передачи метода в качестве параметра при вызове другого метода. Они допускают некоторое серьезное разделение, но я бы оставил это для нового вопроса.

что позволило бы мне настроить многие классы с функциональностью Observer, и Publisher больше не нужно знать о них ничего, кроме того, что они могут получать вызов Alert (). Также обратите внимание, что Publisher будет пытаться вызвать Alert для любого и всех Наблюдателей, которые у него есть, даже если у него их нет.

Теперь, в мире C #, язык имеет встроенную версию этого шаблона через его объекты Event. События очень мощные и используют делегатов, что является способом передачи метода в качестве параметра при вызове другого метода. Они допускают некоторое серьезное разделение, но я бы оставил это для нового вопроса.

что позволило бы мне настроить многие классы с функциональностью Observer, и Publisher больше не нужно знать о них ничего, кроме того, что они могут получать вызов Alert (). Также обратите внимание, что Publisher будет пытаться вызвать Alert для любого и всех Наблюдателей, которые у него есть, даже если у него их нет.

Теперь, в мире C #, язык имеет встроенную версию этого шаблона через его объекты Event. События очень мощные и используют делегатов, что является способом передачи метода в качестве параметра при вызове другого метода. Они допускают некоторое серьезное разделение, но я бы оставил это для нового вопроса.

даже если его нет.

Теперь, в мире C #, язык имеет встроенную версию этого шаблона через его объекты Event. События очень мощные и используют делегатов, что является способом передачи метода в качестве параметра при вызове другого метода. Они допускают некоторое серьезное разделение, но я бы оставил это для нового вопроса.

даже если его нет.

Теперь, в мире C #, язык имеет встроенную версию этого шаблона через его объекты Event. События очень мощные и используют делегатов, что является способом передачи метода в качестве параметра при вызове другого метода. Они допускают некоторое серьезное разделение, но я бы оставил это для нового вопроса.

0
ответ дан 1 December 2019 в 06:48
поделиться

Наблюдатель (публикация / подписка)

Когда объект меняет состояние, он уведомляет другие объекты, которые зарегистрировали свой интерес во время выполнения. Уведомляющий объект (издатель) отправляет событие (публикацию) всем своим наблюдателям (подписчикам).

0
ответ дан 1 December 2019 в 06:48
поделиться

alt text
(источник: headfirstlabs.com )
Как уже говорилось, посмотрите « Head First: Design Patterns », у них также есть некоторые форумы, посвященные книге и дизайну медитации .

Шаблон наблюдателя следует голливудскому принципу «Не звоните нам, мы вас зовем»

Хороший сайт для шаблонов http://www.dofactory.com/Patterns/PatternObserver.aspx

1
ответ дан 1 December 2019 в 06:48
поделиться

Представьте, что у вас есть объект, поведение (или состояние) которого вы хотите наблюдать. Например, когда поле A достигает значения 10, вы хотите получать информацию об этом событии без фактической привязки к деталям реализации этого сложного объекта, который вы хотите наблюдать. Вы определяете интерфейс, называете его Observable и позволяете своей цели реализовать этот интерфейс, он должен иметь как минимум два метода для регистрации и отмены регистрации Observer, который, в свою очередь, является объектом, который будет вызываться Observer, когда поле A достигнет 10. Ваш Observer просто вызывает Observable для регистрации (и отмены регистрации, когда закончите). Обычно наблюдаемые ведут список наблюдателей и уведомляют их сразу или по вашему усмотрению. Это также можно сделать синхронно или асинхронно, решать только вам. Это очень упрощенное объяснение без написания кода. Когда вы поймете это, реализации могут отличаться в деталях, чтобы соответствовать вашим конкретным потребностям.

0
ответ дан 1 December 2019 в 06:48
поделиться

В самых простых терминах есть два компонента: Наблюдатель и Наблюдаемый.

Внешне Наблюдателю нужен способ добавить (зарегистрироваться) и удалить Наблюдателя.
Внутренне, Наблюдателю нужен список зарегистрированных Наблюдателей.

Наблюдателю нужен открытый метод, такой как Notify () или Notify (params).

Каждый раз, когда с Наблюдателем происходит какая-то конкретная вещь, он будет проходить по списку. и вызывать Notify () для каждого зарегистрированного наблюдателя.

В простейшем случае это простое уведомление, которое гласит: «Эй, наблюдатель, мои данные изменены, приходите и обновите себя» В более сложных версиях параметры могут быть в прошлом, позволяя наблюдателю знать, что изменилось.

В Model-View-Controller наблюдаемый обычно является объектом-сущностью - чем-то, что содержит данные. Контролер является Наблюдателем. Он следит за изменениями в модели и сообщает представлению обновить себя, если он заинтересован в этих изменениях.

Слушатели событий Java представляют собой реальную реализацию этого шаблона.

0
ответ дан 1 December 2019 в 06:48
поделиться

Этот шаблон, вероятно, один из самых основных, если не самый базовый шаблон.

Есть вовлечены два «человека»; издатель и подписчик / наблюдатель .

Наблюдатель просто просит издателя уведомлять его, когда появляются «новости». Новости могут быть чем-то важным здесь. Это может быть температура воздуха, это может быть новый пост на сайте, это может быть время суток.

1
ответ дан 1 December 2019 в 06:48
поделиться

Observer is like a direct line of communication. Rather than have all your relatives call you to find out how you are, when you get sick write a card and everyone who is interested gets it (or a copy). When you get better, you send out a card. When you stub your toe, you send out a card. When you get an A, you send out a card.

Anyone who cares gets on your mass mailing list and can respond however they see fit.

This dependency is great for UI. If I have a process that is slow (for example), it can fire an even when progress is made. A progress bar element could observe that and update its coverage. An OK button could observe that and become active at 100%. A cursor could observe that an animate until the progress is 100%. None of these observers needs to know about each other. Furthermore, none of these elements strictly needs to know what is driving them either.

1
ответ дан 1 December 2019 в 06:48
поделиться

Шаблон наблюдателя такой же, как и звучит -

Это средство для некоторых объектов наблюдать объект, наблюдая это для изменений.

В C # это становится несколько проще, поскольку события в основном являются языковым средством реализации шаблона наблюдателя. Если вы когда-либо использовали события, вы использовали шаблон наблюдателя.

В других языках это не встроено, поэтому было много попыток формализовать подходы к обработке этого.

1
ответ дан 1 December 2019 в 06:48
поделиться

Наблюдатель хочет знать, когда что-то меняется, поэтому он подписывается на Субъект. Субъект не знает Наблюдателя. Это важная часть. Субъект просто определяет интерфейс (или делегат), который должен предоставить наблюдатель, и разрешает регистрацию.

Короче говоря: шаблон Наблюдатель позволяет вашему наблюдателю вызываться из субъекта, которому все равно, кто является наблюдателем, и если он даже существует.

3
ответ дан 1 December 2019 в 06:48
поделиться

Посмотрите "Head First: Design Patterns" для некоторых действительно, чмокайте в лоб легко следовать описаниям основных моделей.

Для Обозревателя важно понимать, что оно описывает отношение «один ко многим» и использует модель подписки для сообщения другим классам, когда произошли изменения. RSS, Atom и Twitter работают в этом направлении.

5
ответ дан 1 December 2019 в 06:48
поделиться

Есть два объекта NOTIFIER и OBSERVER. NOTIFIER ничего не знает о OBSERVER, в то время как OBSERVER знает, что NOTIFER реализует событие.

OBSERVER использует это событие для информирования других объектов о том, что что-то произошло. Просто произнесенное событие - это список методов. Поскольку OBSERVER хочет получать уведомления, если что-то произошло, OBSERVER добавляет метод, который должен вызываться, если что-то происходит, к событию NOTIFER.

Поэтому, если что-то случится, NOTIFIER публикует с этим событием, NOTIFIER просто обходит список методов и их вызовы. Когда вызывается метод, добавленный OBSERVER, OBSERVER знает, что это произошло, и может сделать то, что когда-либо потребуется в этом случае.

Вот пример класса уведомителя с событием ValueChanged () .

// Declare how a method must look in order to be used as an event handler.
public delegate void ValueChangedHandler(Notifier sender, Int32 oldValue, Int32 newValue);

public class Notifier
{
    // Constructor with an instance name.
    public Notifier(String name)
    {
        this.Name = name;
    }
    public String Name { get; private set; }

    // The event that is raised when ChangeValue() changes the
    // private field value.
    public event ValueChangedHandler ValueChanged;

    // A method that modifies the private field value and
    // notifies observers by raising the ValueChanged event.
    public void ChangeValue(Int32 newValue)
    {
        // Check if value really changes.
        if (this.value != newValue)
        {
            // Safe the old value.
            Int32 oldValue = this.value;

            // Change the value.
            this.value = newValue;

            // Raise the ValueChanged event.
            this.OnValueChanged(oldValue, newValue);
        }
    }

    private Int32 value = 0;

    // Raises the ValueChanged event.
    private void OnValueChanged(Int32 oldValue, Int32 newValue)
    {
        // Copy the event handlers - this is for thread safty to
        // avoid that somebody changes the handler to null after
        // we checked that it is not null but before we called
        // the handler.
        ValueChangedHandler valueChangedHandler = this.ValueChanged;

        // Check if we must notify anybody.
        if (valueChangedHandler != null)
        {
            // Call all methods added to this event.
            valueChangedHandler(this, oldValue, newValue);
        }
    }
}

Вот пример класса наблюдателя.

public class Observer
{
    // Constructor with an instance name.
    public Observer(String name)
    {
        this.Name = name;
    }
    public String Name { get; private set; }

    // The method to be registered as event handler.
    public void NotifierValueChanged(Notifier sender, Int32 oldValue, Int32 newValue)
    {
        Console.WriteLine(String.Format("{0}: The value of {1} changed from {2} to {3}.", this.Name, sender.Name, oldValue, newValue));
    }
}

Небольшое тестовое приложение.

class Program
{
    static void Main(string[] args)
    {
        // Create two notifiers - Notifier A and Notifier B.
        Notifier notifierA = new Notifier("Notifier A");
        Notifier notifierB = new Notifier("Notifier B");

        // Create two observers - Observer X and Observer Y.
        Observer observerX = new Observer("Observer X");
        Observer observerY = new Observer("Observer Y");

        // Observer X subscribes the ValueChanged() event of Notifier A.
        notifierA.ValueChanged += observerX.NotifierValueChanged;

        // Observer Y subscribes the ValueChanged() event of Notifier A and B.
        notifierA.ValueChanged += observerY.NotifierValueChanged;
        notifierB.ValueChanged += observerY.NotifierValueChanged;

        // Change the value of Notifier A - this will notify Observer X and Y.
        notifierA.ChangeValue(123);

        // Change the value of Notifier B - this will only notify Observer Y.
        notifierB.ChangeValue(999);

        // This will not notify anybody because the value is already 123.
        notifierA.ChangeValue(123);

        // This will not notify Observer X and Y again.
        notifierA.ChangeValue(1);
    }
}

Вывод будет следующим.

Observer X: The value of Notifier A changed from 0 to 123.
Observer Y: The value of Notifier A changed from 0 to 123.
Observer Y: The value of Notifier B changed from 0 to 999.
Observer X: The value of Notifier A changed from 123 to 1.
Observer Y: The value of Notifier A changed from 123 to 1.

Чтобы понять типы делегатов, я собираюсь сравнить их с типами классов.

public class Example
{
   public void DoSomething(String text)
   {
      Console.WriteLine(
         "Doing something with '" + text + "'.");
   }

   public void DoSomethingElse(Int32 number)
   {
      Console.WriteLine(
         "Doing something with '" + number.ToString() + "'.");
   }
}

Мы определили простой класс Пример с двумя методами. Теперь мы можем использовать этот тип класса.

Example example = new Example();

Хотя это работает, следующее не работает, потому что типы не совпадают. Вы получаете ошибку компилятора.

Example example = new List<String>();

И мы можем использовать переменную , пример .

example.DoSomething("some text");

Теперь то же самое с типом делегата. Сначала мы определяем тип делегата - это просто определение типа, подобное определению класса ранее.

public delegate void MyDelegate(String text);

Теперь мы можем использовать тип делегата, но мы не можем хранить обычные данные в переменной типа делегата, но метод.

MyDelegate method = example.DoSomething;

Мы Теперь сохранили метод DoSomething () объекта , пример . Следующее не работает, потому что мы определили MyDelegate как делегат, принимающий один строковый параметр и возвращающий void. DoSomethingElse возвращает void, но принимает целочисленный параметр, поэтому вы получаете ошибку компилятора.

MyDelegate method = example.DoSomethingElse;

И, наконец, вы можете использовать метод переменной . Вы не можете выполнять манипулирование данными, потому что переменная хранит не данные, а метод. Но вы можете вызвать метод, хранящийся в переменной.

method("Doing stuff with delegates.");

Это вызывает метод, который мы сохранили в переменной - example.DoSomething () .

2
ответ дан 1 December 2019 в 06:48
поделиться

Возможно, у вас проблемы с определением правильных интерфейсов. Интерфейс определяет взаимодействие между подписчиком и издателем.

Сначала создайте приложение на C # WinForms

Настройте Program.cs следующим образом

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Application.Run(new Form1());
        }
    }

    interface IObserver
    {
        void Refresh(List<string> DisplayList);
    }

    class ObserverList : List<IObserver>
    {
        public void Refresh(List<String> DisplayList)
        {
            foreach (IObserver tItem in this)
            {
                tItem.Refresh(DisplayList);
            }
        }

    }
}

Здесь мы делаем две вещи. Первый интерфейс, который будут реализованы подписчиками. Затем список для издателя, который будет содержать всех подписчиков.

Затем создайте форму, одну с двумя кнопками, одну с надписью Форма 2, а другую с пометкой Форма 3. Затем добавьте текстовое поле, затем еще одну кнопку с надписью Добавить

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private List<string> DataList= new List<string>();
        private ObserverList MyObservers = new ObserverList();
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 frmNewForm = new Form2();
            MyObservers.Add(frmNewForm);
            frmNewForm.Show();
            MyObservers.Refresh(DataList);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Form3 frmNewForm = new Form3();
            MyObservers.Add(frmNewForm);
            frmNewForm.Show();
            MyObservers.Refresh(DataList);

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            DataList.Add(textBox1.Text);
            MyObservers.Refresh(DataList);
            textBox1.Text = "";
        }

    }
}

Я намеренно установил. вверх кнопку Form2 и кнопку FOrm3, чтобы сделать несколько копий каждого типа формы. Например, у вас может быть двенадцать сразу.

Вы заметите, что после создания каждой формы я помещаю ее в список наблюдателей. Я могу сделать это, потому что как Form2, так и Form3 реализуют IObserver. После того, как я показываю форму, я вызываю команду refresh в списке наблюдателей, поэтому новая форма обновляется с использованием самых последних данных. Обратите внимание, что я мог бы привести его к переменной IObserver и обновить только эту форму. Я стараюсь быть как можно более кратким.

Затем для кнопки «Добавить» Button3 я извлекаю текст из текстового поля, сохраняю его в своем DataList и затем обновляю всех наблюдателей.

Затем создаем Form2. Добавьте список и следующий код.

с помощью System;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form2 : Form,IObserver
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {

        }

        void IObserver.Refresh(List<string> DisplayList)
        {
            this.listBox1.Items.Clear();
            foreach (string s in DisplayList)
            {
                this.listBox1.Items.Add(s);
            }
            this.listBox1.Refresh();
        }

    }
}

Затем добавьте поле со списком Form3 и добавьте следующий код.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form3 : Form,IObserver
    {
        public Form3()
        {
            InitializeComponent();
        }

        private void Form3_Load(object sender, EventArgs e)
        {

        }
        void IObserver.Refresh(List<string> DisplayList)
        {
            this.comboBox1.Items.Clear();
            foreach (string s in DisplayList)
            {
                this.comboBox1.Items.Add(s);
            }
            this.comboBox1.Refresh();
        }
    }
}

Вы заметите, что каждая форма реализует метод обновления интерфейса IObserver, немного отличающийся. Один для списка, другой для поля со списком. Использование интерфейсов является ключевым элементом здесь.

В реальном приложении этот пример был бы более сложным. Например, вместо передачи списка строк в интерфейсе обновления. Это не будет иметь никаких параметров. Вместо этого издатель (в данном примере Form1) реализует интерфейс издателя и регистрируется у наблюдателей по мере их инициализации. Каждый наблюдатель сможет принять издателя в своей процедуре инициализации. Затем, когда он обновляется, он вытягивает список строк из Publisher с помощью метода, предоставляемого через интерфейс.

Для более сложных приложений с несколькими типами данных это позволяет настроить, какие данные форма, реализующая IObserver, извлекает из издателя.

Конечно, если вы ТОЛЬКО хотите, чтобы наблюдатель мог отображать список строк или конкретные данные. Затем передайте его как часть параметров. Интерфейс делает явным то, что хочет сделать каждый слой.

1
ответ дан 1 December 2019 в 06:48
поделиться

Те, кто предположил, что события в .NET действительно являются реализацией паттерна Observer, не тянут вашу цепочку; это правда. Что касается того, как это работает на самом деле, как с точки зрения высокого уровня, так и с точки зрения деталей, связанных с реализацией, я воспользуюсь аналогией.

Подумайте об издателе газеты. В терминах ООП мы могли бы думать о газете как о наблюдаемой вещи.Но как это работает? Очевидно, что детали реализации самой газеты (то есть, в этой аналогии, журналисты, писатели, редакторы и т. Д., Которые работают в офисе, чтобы собрать газету), публично не разглашаются. Люди ( наблюдатели ) не собираются вместе и не смотрят, как сотрудники редакции газеты делают свою работу. Они не могут просто сделать это, потому что для этого не существует протокола (или интерфейса ).

Вот как вы наблюдаете (т. Е. Читаете) газету: вы подписываетесь на нее. Вы включаете свое имя в список подписчиков этой газеты, а затем издатель знает, что каждое утро нужно доставить его прямо к вам на порог. Если вы больше не хотите его наблюдать (читать), вы отказываетесь от подписки; вы убрали ваше имя из этого списка.

Это может показаться абстрактной аналогией; но на самом деле это почти идеальная параллель тому, как работают события .NET .

Учитывая, что некоторый класс должен быть наблюдаемым, его реализация в целом не обязательно должна быть известна публике. Однако он предоставит публике определенный вид интерфейса, и этот интерфейс является событием. Код, который хочет наблюдать это событие, по сути, регистрируется как подписчик:

// please deliver this event to my doorstep
myObject.SomeEvent += myEventHandler;

Когда этот же код решает, что больше не хочет получать уведомления об этом событии, он отписывается:

// cancel my subscription
myObject.SomeEvent -= myEventHandler;

Теперь быстро обсудим делегатов и то, как этот код действительно работает. Делегат, как вы можете знать или не знать, по сути, представляет собой переменную, в которой хранится адрес метода.Обычно эта переменная имеет тип - как и переменные value , объявленные как int , double , string и т. Д., Все имеют типы . В случае типов делегатов этот тип определяется сигнатурой метода ; то есть его параметры и возвращаемое значение. Делегат определенного типа может указывать на любой метод, который выполняет любое действие , если этот метод имеет соответствующую сигнатуру.

Итак, вернемся к аналогии с газетой: чтобы успешно подписаться на газету, вы должны действительно следовать определенной схеме. В частности, вам необходимо указать действующий адрес, по которому вы хотите доставить газету. Вы не можете просто сказать: «Да, отправьте это Дэну». Вы не можете сказать: «Я съем чизбургер с беконом». Вы должны предоставить издателю информацию, с которой он сможет эффективно работать. В мире событий .NET это означает необходимость предоставить обработчик событий с правильной подписью.

В большинстве случаев эта сигнатура оказывается некоторым методом вроде этого:

public void SomeEventHandler(object sender, EventArgs e) {
    // anything could go in here
}

Вышеупомянутый метод может быть сохранен в переменной делегата типа EventHandler . Для более конкретных случаев существует общий тип делегата EventHandler , который описывает метод, аналогичный приведенному выше, но с параметром e некоторого типа , производным от EventArgs .

Имея в виду, что делегаты на самом деле являются переменными, указывающими на методы, нетрудно установить окончательную связь между ними.NET событий и подписки на газеты. События реализуются через список делегатов, в / из которых элементы могут быть добавлены и удалены. Это действительно похоже на список подписчиков газетного издания,каждый из них получает копию при раздаче газет каждое утро.

В любом случае, надеюсь, это помогло вам немного разобраться в шаблоне наблюдателя. Конечно, существует множество других вариантов реализации этого шаблона, но события .NET - это парадигма, с которой знакомо большинство разработчиков .NET, поэтому я думаю, что это хорошая отправная точка для развития понимания.

0
ответ дан 1 December 2019 в 06:48
поделиться

Очень мало примеров в реальном времени:

  1. Газета / Журнал / Список рассылки Подписка или любая подписка в целом
  2. Отметка коллеги в MS Office Коммуникатор
  3. Twitter
0
ответ дан 1 December 2019 в 06:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: