观察者模式

/**
 * @Title : 被观察者接口
 * @author qiucd
 * @date 2016-1-21
 */
public interface Observable {
    /**
     * 增加一个观察者
     * @param observer
     */
    public void addObserver(Observer observer);

    /**
     * 删除一个观察者
     * @param observer
     */
    public void deleteObserver(Observer observer);

    /**
     * 既然要观察,我发生改变了他也应该有所动作,通知观察者
     * @param context
     */
    public void notifyObservers(String context);
}   

/**
 * @Title : 观察者接口
 * @author qiucd
 * @date 2016-1-21
 */
public interface Observer {
    //一发现别人有动静,自己也要行动起来
    public void update(String context);
}

/**
 * @Title : 被观察者接口
 * @author qiucd
 * @date 2016-1-21
 */
public interface IHanFeiZi {

    /**
     * 韩非子也是人,也要吃早饭的
     */
    public void haveBreakfast();

    /**
     * 韩非子也是人,是人就要娱乐活动
     */
    public void haveFun();
}

/**
 * @Title : 被观察者实现类
 * @author qiucd
 * @date 2016-1-21
 */
public class HanFeiZi implements Observable,IHanFeiZi {

    //定义个变长数组,存放所有的观察者
    private ArrayList<Observer> observerList = new ArrayList<Observer>();

    //增加观察者
    public void addObserver(Observer observer) {
        this.observerList.add(observer);
    }

    //删除观察者
    public void deleteObserver(Observer observer) {
        this.observerList.remove(observer);
    }

    //通知所有的观察者
    public void notifyObservers(String context) {
        for(Observer obs : observerList){
            obs.update(context);
        }
    }

    @Override
    public void haveBreakfast() {
        System.out.println("韩非子:开始吃饭了...");
        this.notifyObservers("韩非子在吃饭");
    }

    @Override
    public void haveFun() {
        System.out.println("韩非子:开始娱乐了...");
        this.notifyObservers("韩非子在娱乐");
    }
}

public class LiSi implements Observer {

    //首先李斯是个观察者,一旦韩非子有活动,他就知道,他要开始向老板汇报
    public void update(String context) {
        System.out.println("李斯:观察到韩非子活动,开始向老板汇报...");
        this.reportToQinShiHuang(context);
        System.out.println("李斯:汇报完毕!");
    }

    private void reportToQinShiHuang(String reprotContext){
        System.out.println("李斯:报告,秦老板! 韩非子有活动了-----> "+reprotContext);
    }
}

public class LiuSi implements Observer {

    //刘斯,观察到韩非子活动后,自己也得做一些事
    public void update(String context) {
        System.out.println("刘斯:观察者到韩非子活动,自己也开始活动了...");
        this.happy(context);
        System.out.println("刘斯:乐死了...\n");
    }

    private void happy(String context){
        System.out.println("刘斯:因为"+context+",--所以我快乐呀!");
    }
}

public class WangSi implements Observer {

    //王斯,看到韩非子有活动
    public void update(String context) {
        System.out.println("王斯:观察者到韩非子活动,自己也开始活动了...");
        this.cry(context);
        System.out.println("王斯:哭死了...\n");
    }

    private void cry(String str){
        System.out.println("王斯:因为"+str+",--所以我悲伤呀!");
    }

}

/**
 * @Title : 观察者模式
 * @author qiucd
 * @date 2016-1-21
 */
public class Client {
    public static void main(String[] args) {
        //三个观察者产生出来
        Observer liSi = new LiSi();
        Observer wangSi = new WangSi();
        Observer liuSi = new LiuSi();

        //定义韩非子
        HanFeiZi hanFeiZi = new HanFeiZi();


        //我们后人根据历史,描述这个场景,有三个人在观察韩非子
        hanFeiZi.addObserver(liSi);
        hanFeiZi.addObserver(wangSi);
        hanFeiZi.addObserver(liuSi);

        //然后这里我们看看韩非子在干什么;
        hanFeiZi.haveBreakfast();
    }
}

运行结果:
    韩非子:开始吃饭了...
    李斯:观察到韩非子活动,开始向老板汇报...
    李斯:报告,秦老板! 韩非子有活动了-----> 韩非子在吃饭
    李斯:汇报完毕!
    王斯:观察者到韩非子活动,自己也开始活动了...
    王斯:因为韩非子在吃饭,--所以我悲伤呀!
    王斯:哭死了...

    刘斯:观察者到韩非子活动,自己也开始活动了...
    刘斯:因为韩非子在吃饭,--所以我快乐呀!
    刘斯:乐死了...

观察者模式的注意事项:

广播链问题:

如果你做过数据库的触发器,你就应该知道有一个触发器链的问题,比如 表A上写了一个触发器,内容是一个字段更新后更新表B的一条数据,而表B上也有个触发器,要更新表C,表C也有触发器… 完蛋了,这个数据库基本上毁掉了!我们的观察者模式也是一样的问题,一个观察者可以有双重身份,既是观察者,也是被观察者,这没什么问题呀,但是链一旦建立,这个逻辑就比较复杂,可维护非常差,所以建议,在一个观察者模式中最多出现一个对象既是观察者也是被观察者,也就是说消息最多转发一次(传递两次),这还是比较好控制的。

它和责任链模式的最大区别就是观察者广播链的过程中消息是随时更改的,它是由相邻的两个节点协商的消息结构;而责任链模式在消息传递过程中基本上保持消息不可变,如果要改变,也只是在原有的消息上进行修正。

异步处理问题:
EJB是一个非常好的例子,被观察者发生动作了,观察者要做出回应,如果观察者比较多,而且处理时间比较长怎么办?那就用异步呗,异步处理就要考虑线程安全和队列安全的问题,这个大家有时间看看Message Queue,就会有更深的了解。


订阅发布模型:

观察者也叫发布/订阅模型(Publish/Subscribe),如果你做过EJB的开发,这个你绝对不陌生,EJB是个折腾死人不偿命的玩意,写个Bean要实现,还要继承,再加上一堆的配置文件,小项目凑合,要知道EJB开发的基本上都不是小项目,到最后是每个项目成员都在骂EJB这个忽悠人的东西;但EBJ3是个非常优秀的框架,还是算比较轻量级,写个Bean只要加个Annotaion就成了,配置文件减少了。而且引入了依赖注入的概念。虽然只是EJB2的翻版,但是毕竟还是前进了一步。在EJB中有3个类型的Bean:Session Bean,Entity Bean和MessageDriven Bean, 说下MessageDriven Bean(一般简称MDB),消息驱动Bean,消息的发布者(Provider) 发布一个消息,也就是一个消息驱动Bean,通过EJB容器(一般是Message Queue消息队列) 通知订阅者做出回应,从原理上看很简单,就是观察者模式的升级版,或者说是观察者模式的BOSS版。

源码来自:https://pan.quark.cn/s/a3a3fbe70177 AppBrowser(Application属性查看器,不需要越狱! ! ! ) 不需要越狱,调用私有方法 --- 获取完整的已安装应用列表、打开和删除应用操作、应用运行时相关信息的查看。 支持iOS10.X 注意 目前AppBrowser不支持iOS11应用查看, 由于iOS11目前还处在Beta版, 系统API还没有稳定下来。 等到Private Header更新了iOS11版本,我也会进行更新。 功能 [x] 已安装的应用列表 [x] 应用的详情界面 (打开应用,删除应用,应用的相关信息展示) [x] 应用运行时信息展示(LSApplicationProxy) [ ] 定制喜欢的字段,展示在应用详情界面 介绍 所有已安装应用列表(应用icon+应用名) 为了提供思路,这里只用伪代码,具体的私有代码调用请查看: 获取应用实例: 获取应用名和应用的icon: 应用列表界面展示: 应用列表 应用运行时详情 打开应用: 卸载应用: 获取info.plist文件: 应用运行时详情界面展示: 应用运行时详情 右上角,从左往右第一个按钮用来打开应用;第二个按钮用来卸载这个应用 INFO按钮用来解析并显示出对应的LSApplicationProxy类 树形展示LSApplicationProxy类 通过算法,将LSApplicationProxy类,转换成了字典。 转换规则是:属性名为key,属性值为value,如果value是一个可解析的类(除了NSString,NSNumber...等等)或者是个数组或字典,则继续递归解析。 并且会找到superClass的属性并解析,superClass如...
基于遗传算法辅助异构改进的动态多群粒子群优化算法(GA-HIDMSPSO)的LSTM分类预测研究(Matlab代码实现)内容概要:本文研究了一种基于遗传算法辅助异构改进的动态多群粒子群优化算法(GA-HIDMSPSO),并将其应用于LSTM神经网络的分类预测中,通过Matlab代码实现。该方法结合遗传算法的全局搜索能力与改进的多群粒子群算法的局部优化特性,提升LSTM模型在分类任务中的性能表现,尤其适用于复杂非线性系统的预测问题。文中详细阐述了算法的设计思路、优化机制及在LSTM参数优化中的具体应用,并提供了可复现的Matlab代码,属于SCI级别研究成果的复现与拓展。; 适合群:具备一定机器学习和优化算法基础,熟悉Matlab编程,从事智能算法、时间序列预测或分类模型研究的研究生、科研员及工程技术员。; 使用场景及目标:①提升LSTM在分类任务中的准确性与收敛速度;②研究混合智能优化算法(如GA与PSO结合)在神经网络超参数优化中的应用;③实现高精度分类预测模型,适用于电力系统故障诊断、电池健康状态识别等领域; 阅读建议:建议读者结合Matlab代码逐步调试运行,理解GA-HIDMSPSO算法的实现细节,重点关注种群划分、异构策略设计及与LSTM的集成方式,同时可扩展至其他深度学习模型的参数优化任务中进行对比实验。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值