观察者模式

对于观察者模式还不是特别大额理解,现在那么静静下心来好好的整理了一下。
自己理解搞这么多的设计模式到底是干什么? 解耦和模块化。试着想象,现在很吊的滴滴打车,曾经出现了很多的黑科技优惠券,不就是由于发展太快,解耦处理不好,出现了很多的‘黑科技’。(刚开始写,表达能力不是很强,后期我会慢慢的优化的。)

首先

观察者模式要做到

  • 开放-封闭原则(修改原有的代码就代表不好)。
  • 依赖倒转原则(应该让程序都依赖抽象,而不是相互依赖)。
    让耦合的双方都依赖于抽象,而不是依赖于具体,从而使各自的变化都不会影响到另一边的变化。

到底观察者模式是什么样子的呢?

用一张图来解释观察者模式
观察者模式

代码来源(书籍):大话设计模式

//Subject类,可翻译为主题或抽象通知者,一般用一个抽象类或一个接口实现。它把所有对观察者对象的引用保存在一个聚集里面,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以拉回和删除观察者对象。  
public abstract class Subject  
{  
    private List<Observer>    observers   = new ArrayList<Observer>();  

    public void attach(Observer observer)  
    {  
        observers.add(observer);  
    }  

    public void detach(Observer observer)  
    {  
        observers.remove(observer);  
    }  

    public void announce()  
    {  
        for (Observer obj : observers)  
        {  
            obj.update();  
        }  
    }  
}  
//Observer类,抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。抽象观察者一般用一个抽象类或者一个接口实现。更新接口通常包含一个update()方法,这个方法叫做更新方法。  
public abstract class Observer  
{  
    public abstract void update();  
}  
//ConcreteSubject类,叫做具体主题或具体通知者,将有关状态存入具体观察者对象,在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。  
public class ConcreteSubject extends Subject  
{  
    // 具体被观察者状态  
    private String  subjectState;  

    public String getSubjectState()  
    {  
        return subjectState;  
    }  

    public void setSubjectState(String subjectState)  
    {  
        this.subjectState = subjectState;  
    }  
}  
//ConcreteObserver类,具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。具体观察者角色可以保存一个指向具体主题对象的引用。具体观察者角色通常用一个具体子类实现。  
public class ConcreteObserver extends Observer  
{  
    private String          name;  
    private String          observerState;  
    private ConcreteSubject subject;  

    public ConcreteObserver(String name, ConcreteSubject subject)  
    {  
        this.name = name;  
        this.subject = subject;  
    }  

    public void update()  
    {  
        observerState = subject.getSubjectState();  
        System.out.println("观察者" + name + "的新状态是" + observerState);  
    }  

    public ConcreteSubject getSubject()  
    {  
        return subject;  
    }  

    public void setSubject(ConcreteSubject subject)  
    {  
        this.subject = subject;  
    }  
}  
//客户端代码  
public class Main  
{  
    public static void main(String[] args)  
    {  
        ConcreteSubject s = new ConcreteSubject();  

        s.attach(new ConcreteObserver("X", s));  
        s.attach(new ConcreteObserver("Y", s));  
        s.attach(new ConcreteObserver("Z", s));  

        s.setSubjectState("ABC");  
        s.announce();  
    }  
}  
结果显示:  
观察者X的新状态是ABC  
观察者Y的新状态是ABC  
观察者Z的新状态是ABC  

但是这样的话,抽象通知者还是依赖观察者

万一没有抽象观察者这样的接口,那么我们的观察者模式还是完成不了

用委托来解决

EventHandler(事件处理程序)
用委托的方式来进行通知每个具体的观察者的不同的updata的处理方法。

但是委托也是有前提的,那么就是委托对象所搭载的所有的方法必须具有相同的原型和形式,也就是拥有相同的返回值类型和参数列表

代码来源(书籍):大话设计模式

 //看股票的同事  
    class StockObserver  
    {  
        private string name;  
        private Subject sub;  
        public StockObserver(string name, Subject sub)  
        {  
            this.name = name;  
            this.sub = sub;  
        }  

        //关闭股票行情  
        public void CloseStockMarket()  
        {  
            Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, name);  
        }  
    }  

    //看NBA的同事  
    class NBAObserver  
    {  
        private string name;  
        private Subject sub;  
        public NBAObserver(string name, Subject sub)  
        {  
            this.name = name;  
            this.sub = sub;  
        }  

        //关闭NBA直播  
        public void CloseNBADirectSeeding()  
        {  
            Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);  
        }  
    }  
//抽象通知者由于不希望依赖于抽象观察者,所以增加和减少的就没有必要了,抽象观察者已经不存在了,通知者接口如下  
    //通知者接口  
    interface Subject  
    {  
        void Notify();  
        string SubjectState  
        {  
            get;  
            set;  
        }  
    }  
//事件处理程序的委托  
delegate void EventHandler();  
//老板类和前台秘书类  
    class Secretary : Subject  
    {  
        //声明一事件Update,类型为委托EventHandler  
        public event EventHandler Update;  

        private string action;  

        public void Notify()  
        {  
            Update();  
        }  
        public string SubjectState  
        {  
            get { return action; }  
            set { action = value; }  
        }  
    }  

    class Boss : Subject  
    {  
        //声明一事件Update,类型为委托EventHandler  
        public event EventHandler Update;  

        private string action;  

        public void Notify()  
        {  
            Update();  
        }  
        public string SubjectState  
        {  
            get { return action; }  
            set { action = value; }  
        }  
}  
//客户端代码  
class Program  
    {  
        static void Main(string[] args)  
        {  
            //老板胡汉三  
            Boss huhansan = new Boss();  

            //看股票的同事  
            StockObserver tongshi1 = new StockObserver("魏关姹", huhansan);  
            //看NBA的同事  
            NBAObserver tongshi2 = new NBAObserver("易管查", huhansan);  

            huhansan.Update += new EventHandler(tongshi1.CloseStockMarket);  
            huhansan.Update += new EventHandler(tongshi2.CloseNBADirectSeeding);  

            //老板回来  
            huhansan.SubjectState = "我胡汉三回来了!";  
            //发出通知  
            huhansan.Notify();  

            Console.Read();  
        }  
}  
运行结果:  
老板回来了!  魏关姹关闭股票行情,继续工作!  
老板回来了!  易管查关闭股票行情,继续工作!  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值