傍観者モード

17459 ワード

ニュース購読メカニズム

  • 新聞社出版新聞
  • サブスクライバが購読した後、新聞の提供を続けます.新聞が更新されるかどうかにかかわらず、購読者は受け取り続けます.
  • の購読をキャンセルすると、受信されません.
  • 似たような原理で動作するのは傍観者モードである.
    Subjectオブジェクトでデータを管理し、observerオブジェクトでデータを変更したときに配布します.
    オブザーバーのオブザーバーが存在する可能性があります.

    ルースカップリング


    ゆるやかな結合は相互作用しているが相手を理解していない状態である.この結合はオブジェクト向け設計の核心である.

    API VSインタフェースの実装


    Javaに内蔵された観察可能なスーパークラスを使用する方法と、インタフェースを直接使用して実装する方法の2つがあります.

    API実装


    Observerableはクラスです.継承クラスが書き込まれるサブクラスを作成する必要があります.すでに他のクラスを使用している場合は、この機能は使用できません.そのため、再利用性が制限されている.また,実装内容を変えることができないという欠点がある.
    また、setChange()以外のすべての関数は保護されているため、外部から呼び出すことはできません.これは継承よりも構成を重視する設計原則に反する.

    インタフェース実装


    Subjectインタフェース
    package wData;
    
    public interface Subject {
        public void registerObserver(Observer o);
        public void removeObserver(Observer o);
        public void notifyObserver();
    }
    
    Observerインタフェース
    package wData;
    
    public interface Observer {
        public void update(float temperature, float humidity, float pressure);
    }
    DisplayElementインタフェース
    package wData;
    
    public interface DisplayElement {
        public void display();
    }
    例を表示
    package wData;
    
    public class CurrentConditionsDisplay implements Observer, DisplayElement {
        private float temperature;
        private float humidity;
        private Subject weatherData;
    
        public CurrentConditionsDisplay(Subject weatherData) {
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }
    
        @Override
        public void display() {
            System.out.println("Current Conditions = " + temperature + "F degrees and " + humidity + "% humidity");
        }
    
        @Override
        public void update(float temperature, float humidity, float pressure) {
            this.temperature = temperature;
            this.humidity = humidity;
            display();
        }
    }
    各ディスプレイは、オプティカル(光学式)ドライブを同時に受信し、インタフェースを表示します.Subjectを実装するWeatherDataを呼び出し、自分を傍観者として登録します.その後、updateで値を更新してdisplay関数に出力する構成があります.
    ファイバ実装
    package wData;
    
    import java.util.ArrayList;
    
    public class WeatherData implements Subject {
        private ArrayList observers;
        private float temperature;
        private float humidity;
        private float pressure;
    
        public WeatherData() {
            observers = new ArrayList();
        }
    
        @Override
        public void registerObserver(Observer o) {
            observers.add(o);
        }
    
        @Override
        public void removeObserver(Observer o) {
            int i = observers.indexOf(o);
            if (i >= 0) {
                observers.remove(i);
            }
        }
    
        @Override
        public void notifyObserver() {
            for (Object o : observers) {
                Observer observer = (Observer) o;
                observer.update(temperature, humidity, pressure);
            }
        }
    
        public void measurementsChanged() {
            notifyObserver();
        }
    
        public void setMeasurements(float temperature, float humidity, float pressure) {
            this.temperature = temperature;
            this.humidity = humidity;
            this.pressure = pressure;
            measurementsChanged();
        }
    }
    サブオブジェクトインタフェースを継承し、具体的な機能を実現します.
    オプティカル(光学式)ドライブの機能のため、値が変化した場合は、すべてのオプティカル(光学式)ドライブに通知します.
    これはsetMeasurementによって実現される.
    setterで値を設定すると、notifyを呼び出してすべての関数に渡し、更新するmeasurementChanged関数が呼び出されます.

    実行

    package wData;
    
    public class WeatherStation {
        public static void main(String[] args) {
            WeatherData weatherData = new WeatherData();
    
            CurrentConditionsDisplay cd = new CurrentConditionsDisplay(weatherData);
            //StatisticsDisplay staticsDisplay = new StatisticsDisplay(weatherData);
            //ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
    
            weatherData.setMeasurements(80, 65, 30.4f);
            weatherData.setMeasurements(82, 70, 29.2f);
            weatherData.setMeasurements(78, 90, 29.2f);
        }
    }
    コメント処理されたコードは、別の表示例です.
    このように実現して出力することができる.
    Current Conditions = 80.0F degrees and 65.0% humidity
    Current Conditions = 82.0F degrees and 70.0% humidity
    Current Conditions = 78.0F degrees and 90.0% humidity

    整理する


  • 傍観者モードでは,主題の状態と傍観者の数,形式が変化する.このモードでは、トピックを変更することなく、トピックに依存するオブジェクトを変更できます.これは変化に有利である.

  • インタフェースでプログラミングしたほうがいいです.階級がみな中傷するはずがない.親が何人かであるはずがないからだ.
  • CというクラスがA,Bクラスの一部の機能を使用する場合.この場合、二重継承はできないため、この機能部分を書き込むにはインタフェースを使用する必要があります.
    しかし、逆の場合もある.A,BクラスがCインタフェースの機能を使用する場合,A,Bが共通に使用する機能もすべて上書きして再定義する.
    でも使えないより不便なほうがいい.
  • 原則:継承よりも構成が重要

    n/a.結論


    オブジェクト向けのプログラミングを頭で理解するだけで、実際に使ったことがほとんどないので、真似をするときには理解できるのかもしれませんが、実際に実現すると、脳が止まってしまいます…