2

我目前正在研究观察者模式,我遇到了一些困惑。

当我阅读这行代码时:

IObserverSubscribe user1= new ConcreteObserverYoutubeUser();

我认为界面IObserverSubscribe user1正在创建和实例化new ConcreteObserverYoutubeUser()。这让我有点困惑,因为通常被声明的同一个类也在实例化。应该是这样的:

IObserverSubscribe user1= new IObserverSubscribe();

为什么界面装饰能够实例化另一个类?

完整代码如下:

主要的:

package observerpattern;

public class ObserverPattern {

    /**
     * The observer pattern is a software design pattern in which
     *  an object, called the subject, maintains a list of its dependents,
     *  called observers, and notifies them automatically of any 
     *  state changes, usually by calling one of their methods.
     *  It is mainly used to implement distributed event handling systems.
     *  The Observer pattern is also a key part in the familiar
     *  Model View Controller (MVC) architectural pattern. 
     */
    public static void main(String[] args) {

        SubjectYouTubeChannel sytc= new SubjectYouTubeChannel();// create youtube channel
        IObserverSubscribe user1= new ConcreteObserverYoutubeUser();
        IObserverSubscribe user2= new ConcreteObserverYoutubeUser();
        IObserverSubscribe moderator1= new ConcreteObserverYoutubeModerator();

        sytc.Subscribe(user1);
        sytc.Subscribe(user2);
        sytc.Subscribe(moderator1);
        sytc.Unsubscribe(user2);

        sytc.notifySubscribers();


    }

}

学科:

package observerpattern;

import java.util.ArrayList;
import java.util.List;
import observerpattern.IObserverSubscribe;

public class SubjectYouTubeChannel {    
    private List<IObserverSubscribe> subscribers = new ArrayList<IObserverSubscribe>(); 
    public void Subscribe(IObserverSubscribe ios){
        subscribers.add(ios);       
    }   
    public void Unsubscribe(IObserverSubscribe ios){        
        subscribers.remove(ios);
    }   
    public void notifySubscribers(){        
        for(IObserverSubscribe ios : subscribers ){         
            ios.Notify();           
        }       
    }
}

界面观察者:

package observerpattern;

public interface IObserverSubscribe {

    void Notify();

}

具体观察者:

package observerpattern;

public class ConcreteObserverYoutubeUser implements IObserverSubscribe{

    @Override
    public void Notify() {
        System.out.println("User watches video, comments, ect");

    }

}
4

3 回答 3

2
new IObserverSubscribe();

这是非法的,因为您不能实例化接口- 根据定义,它们没有任何 ... 方法定义。

IObserverSubscribe user1= new ConcreteObserverYoutubeUser();

这里的左边说的user1atleast IObserverSubscribe类型,即指向一个实例,其类型实现了接口

另一方面,右侧实际上创建一个具体类型的实例并分配给user1. 这是可能的,因为具体类型实现了接口

于 2012-12-27T15:12:23.613 回答
1

IObserverSubscribe user1= new ConcreteObserverYoutubeUser(); 我认为接口 IObserverSubscribe user1 正在创建和实例化新的 ConcreteObserverYoutubeUser()。这让我有点困惑,因为通常被声明的同一个类也在实例化。应该是这样的:

IObserverSubscribe user1= new IObserverSubscribe();

不,您不能实例化接口。

IObserverSubscribe user1= new ConcreteObserverYoutubeUser();

这将创建一个实例,ConcreteObserverYoutubeUser该实例是 的子类(或实现类) IObserverSubscribe

于 2012-12-27T15:12:15.167 回答
1

想想接口的作用以及观察者模式的用途。

ConcreteObserverYoutubeUser 实现了 IObserverSubscribe 接口,因为它需要保证它有“Notify()”方法。因此,所有应该是“IObserverSubscribers”的类都需要在收到通知时特别做一些事情。

如果您可以执行以下操作,它将破坏观察者模式的目的:

 IObserverSubscribe user1= new IObserverSubscribe();

youtube 版主和 youtube 用户具有不同的功能,因此您不能对两者使用相同的 Notify 方法(请参阅下面的修改代码):

用户等级:

 package observerpattern;

 public class ConcreteObserverYoutubeUser implements IObserverSubscribe{ 

     @Override
     public void Notify() {
         sendEmail("A new video was added! It might be a cat video, so you should " +
       "probably view it, vote on it, comment on it, or ignore it.");

     }
     @Override
     public void watchVideo(Video v) {
       //...
     }
     @Override
     public void giggleAtCatVideo() {
         //..
     }


 }

主持人类:

 package observerpattern;

 public class ConcreteObserverYoutubeModerator implements IObserverSubscribe{    
     @Override
     public void Notify() {
         sendEmail("New video added, see if it should be deleted or if there is copyright infringement.");
     } 
     @Override
     public void deleteVideo(Video v) {
         //..
     }
 }

为什么有用?好吧,因为您可以创建另一个类(在本例中为 SubjectYouTubeChannel),它可以保存实现“IObserverSubscribe”接口的对象。当关于该主题的某些事情发生变化时,您可以通知与该主题相关联的每个观察者,以便所有观察者都知道某些事情发生了变化。

一个更好的例子是,如果 SubjectYouTubeChannel 有一个“addVideo”方法(见下文),并且主持人类和用户类中的 notify 方法向他们发送不同的电子邮件,提醒他们注意更改。

package observerpattern;

import java.util.ArrayList;
import java.util.List;
import observerpattern.IObserverSubscribe;

public class SubjectYouTubeChannel {    
    private List<IObserverSubscribe> subscribers = new ArrayList<IObserverSubscribe>(); 
    public void Subscribe(IObserverSubscribe ios){
        subscribers.add(ios);       
    }   
    public void Unsubscribe(IObserverSubscribe ios){        
        subscribers.remove(ios);
    }   
    public void notifySubscribers(){        
        for(IObserverSubscribe ios : subscribers ){         
            ios.Notify();           
        }       
     }
 public void addVideo(Video v){
     //... video add code
        notifySubscribers();
 }
 }

这意味着你可以做这样很酷的事情:

 package observerpattern;

 public class ObserverPattern {

    /**
     * The observer pattern is a software design pattern in which
     *  an object, called the subject, maintains a list of its dependents,
     *  called observers, and notifies them automatically of any 
     *  state changes, usually by calling one of their methods.
     *  It is mainly used to implement distributed event handling systems.
     *  The Observer pattern is also a key part in the familiar
     *  Model View Controller (MVC) architectural pattern. 
     */
    public static void main(String[] args) {

        SubjectYouTubeChannel sytc= new SubjectYouTubeChannel();// create youtube channel
        IObserverSubscribe user1= new ConcreteObserverYoutubeUser();
        IObserverSubscribe user2= new ConcreteObserverYoutubeUser();
        IObserverSubscribe moderator1= new ConcreteObserverYoutubeModerator();
        Video v = new Video() //imagine that class exists

        sytc.Subscribe(user1);
        sytc.Subscribe(user2);
        sytc.Subscribe(moderator1);
        sytc.Unsubscribe(user2);

        sytc.addVideo(v);
    //notifySubscribers() is called within SubjectYouTubeChannel's addVideo() so
    //all users and moderators who subscribe to the channel have been notified with 
    //messages corresponding to what they should do

    }
 }
于 2012-12-27T15:46:54.757 回答