0

来自四人组的设计模式 在此处输入图像描述

为什么字段observers和方法在接口中AttachDetach而方法和字段 在具体子类中?为什么成员按原样分布在主题接口和具体子类中?NotifySubjectGetStateSetStateSubjectStateConcreteSubject

为什么方法Update在接口Observer中,而字段subjectobserverState具体子类中ConcreteObserver?为什么成员按原样分布在观察者接口和具体子类中?

主体和观察者之间似乎没有对称性。例如,为什么 fieldobservers属于 interface Subject,而 fieldsubject属于ConcreteObserver

谢谢。

4

2 回答 2

1

这是一种观察者设计模式。所有的 GOF 模式都将最大限度地使用 OO 原则。如果职责(和状态)在许多子类中是通用的,则需要在基类层次结构中将其升级到可能的最上层。以下演示代码和评论将回答上述问题。确实,某些设计模式(Observer 就是其中之一。请参阅 update() 中的类型转换)违反了 OO 原则。违反这些原则完全没问题,只需要知道我们违反了哪条原则以及为什么违反。并检查 -我们是否获得了比实施中引入的可能的不灵活/损坏更多的好处?

    public interface Observer {
        /**
          * IF THIS METHOD IS NOT HERE SUBJECT WILL NOT BE ABLE TO CALL IT
          * REFER TO OO BASICS - INHERITANCE
          */
        void update(Subject subject);
    }

    public abstract class Subject {
        // THE COMPLETE LOGIC HERE IS INDEPENDENT OF 
        // WHO THE CONCRETE SUBJECT IS.
        // HENCE THIS IS A RIGHT PLACE FOR IT AS PER OO PRINCIPLES
        // NOTE THAT THIS CLASS KNOWS ONLY ABOUT ABSTRACT OBSERVER
        private Set<Observer> observers; 
        public void add(Observer o){/*...*/}
        public void remove(Observer o){/*...*/}
        protected void notifyAllObservers(){
            for (Observer observer : observers) {
                observer.update(this);
            }
        }
    }

    class ConcreteSubject extends Subject {
        /**
         * HERE THERE IS NO NEED TO KNOW THE CONCRETE OBSERVER-
         * By DEFINITION OF THIS PATTERN. 
         * THE JOB HERE IS TO ONLY NOTIFY ALL OBSERVERS THAT "I HAVE CHANGED"
         * ITS OBSERVER'S RESPONSIBILITY TO REACT IN PULL METHOD
         */

         // Concrete Subject state
         // Concrete Subject behavior
        public void specificMethod(){
            //... concrete class specific logic
        }
    }

    class ConcreteObserver implements Observer{
        @Override
        public void update(Subject subject) {
            /**
             * OBSERVE HERE WE NEED TO TYPE CAST, WHICH LEADS TO VIOLATION OF 
             * OO PRINCIPLES. BUT WE GET BENEFIT OF LOOSELY COUPLED OBSERVERS
             * AGAINST THIS EXTRA COST
             * ITS SAFE TO VIOLATE HERE AS OBSERVER INSTANCES MAKE ONLY 
             * SENSE IN CONTEXT WITH SUBJECT AND WILL NEVER BE REUSED AS
             * OBSERVERS IN UNRELATED CONTEXT.
             */
            ((ConcreteSubject)subject).specificMethod();
        }
    }
于 2017-10-01T06:30:28.710 回答
1

Subject 接口中的 GetState 和 SetState 方法将使 Subject 接口依赖于依赖对象的更新方式。这违反了依赖倒置原则。

所有 Subject 接口所做的就是附加一个具体的主题并通知观察者。具体对象的状态如何改变它与此无关。这就是为什么 getState 和 setState 不是主题接口的一部分的原因。

类似的原因,observerState 不是 Observer 接口的一部分。

于 2017-09-30T06:38:03.790 回答