{"id":20662364,"url":"https://github.com/louloulin/zed","last_synced_at":"2025-09-20T02:59:46.879Z","repository":{"id":240460692,"uuid":"117672402","full_name":"louloulin/Zed","owner":"louloulin","description":"设计模式","archived":false,"fork":false,"pushed_at":"2018-01-16T11:08:45.000Z","size":29,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-20T02:59:45.901Z","etag":null,"topics":["java"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/louloulin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-16T10:58:22.000Z","updated_at":"2018-01-29T01:36:37.000Z","dependencies_parsed_at":"2024-05-19T03:33:45.626Z","dependency_job_id":"9455ef08-1f8d-4435-bbae-5ef01c0ca3be","html_url":"https://github.com/louloulin/Zed","commit_stats":null,"previous_names":["godlinchong/zed","louloulin/zed"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/louloulin/Zed","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/louloulin%2FZed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/louloulin%2FZed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/louloulin%2FZed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/louloulin%2FZed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/louloulin","download_url":"https://codeload.github.com/louloulin/Zed/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/louloulin%2FZed/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276038062,"owners_count":25574251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-20T02:00:10.207Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java"],"created_at":"2024-11-16T19:13:50.489Z","updated_at":"2025-09-20T02:59:46.857Z","avatar_url":"https://github.com/louloulin.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 设计模式\n\n### 观察者模式\n   \n观察者模式，又可以称之为发布-订阅模式，观察者，顾名思义，就是一个监听者，类似监听器的存在，一旦被观察/监听的目标发生的情况，就会被监听者发现，从而触发观察者的动作。\n   \n观察者模式多用于实现订阅功能的场景，例如微博的订阅，当我们订阅了某个人的微博账号，当这个人发布了新的消息，就会通知我们。\n#### 观察者模式主要构成\n* 观察者\n* 目标对象\n\n#### 观察者模式的例子\n就以警察监控罪犯的例子来说明观察者模式的，代码如下：\n\n1. 观察者接口：Observer\n\n\t\tpackage com.listener;\n\t\t/**\n\t\t * 观察者模式接口\n\t\t * @author lin\n\t\t * @date 2018-01-16\n\t\t */\n\t\tpublic interface Observer {\n\t\t    /**\n\t\t     * 观察动作\n\t\t     * @param message\n\t\t     * @param name\n\t\t     */\n\t\t    void update(String message,String name);\n\t\t }\n2. 定义两名便衣观察者：Policeman1,Policeman2\n\n\t\timport com.listener.Observer;\n\t\t/**\n\t\t * 便衣警察邹宇\n\t\t */\n\t\tpublic class Policeman1 implements Observer {\n\t\t    /**\n\t\t     * 警察名称\n\t\t     */\n\t\t    private String bname = \"邹宇\";\n\n\t\t    @Override\n\t\t    public void update(String message, String name) {\n\t\t        System.out.println(bname + \":\" + name + \"那里有新情况：\" + message);\n\t\t    }\n\t\t}\n\t\t\n\t\t\n\t\timport com.listener.Observer;\n\t\t/**\n\t\t * 便衣警察\n\t\t */\n\t\tpublic class Policeman2 implements Observer {\n\t\t    /**\n\t\t     * 警察名称\n\t\t     */\n\t\t    private String bname = \"周童\";\n\n\t\t    @Override\n\t\t    public void update(String message, String name) {\n\t\t        System.out.println(bname + \":\" + name + \"那里有新情况：\" + message);\n\t\t    }\n\t\t}\n3. 监控对象接口\n\n\t\t/**\n\t\t * 目标接口\n\t\t * @author lin\n\t\t * @date 2018-01-16\n\t\t */\n\t\tpublic interface Badass {\n\t\t    /**\n\t\t     * 添加便衣观察者\n\t\t     * @param observer\n\t\t     */\n\t\t    void addObserver(Observer observer);\n\t\t    /**\n\t\t     * 移除便衣观察者\n\t\t     * @param observer\n\t\t     */\n\t\t    void removeObserver(Observer observer);\n\t\t\n\t\t    /**\n\t\t     * 通知观察者\n\t\t     * @param message\n\t\t     */\n\t\t    void notice(String message);\n\t\t}\n4. 目标对象的的实现，定义2个罪犯\n\n\t\t/**\n\t\t * 嫌犯大熊\n\t\t */\n\t\tpublic class XianFan1 implements Badass {\n\t\t    /**\n\t\t     * 别称\n\t\t     */\n\t\t    private String name = \"大熊\";\n\t\t    /**\n\t\t     * 定义观察者集合\n\t\t     */\n\t\t    private List\u003cObserver\u003e observerList = new ArrayList\u003cObserver\u003e();\n\t\t\n\t\t    /**\n\t\t     * 增加观察者\n\t\t     *\n\t\t     * @param observer\n\t\t     */\n\t\t    @Override\n\t\t    public void addObserver(Observer observer) {\n\t\t        if (!observerList.contains(observer)) {\n\t\t            observerList.add(observer);\n\t\t        }\n\t\t    }\n\t\t\n\t\t    /**\n\t\t     * 移除观察者\n\t\t     *\n\t\t     * @param observer\n\t\t     */\n\t\t    @Override\n\t\t    public void removeObserver(Observer observer) {\n\t\t        if (observerList.contains(observer)) {\n\t\t            observerList.remove(observer);\n\t\t        }\n\t\t    }\n\t\t\n\t\t    /**\n\t\t     * 通知观察者\n\t\t     *\n\t\t     * @param message\n\t\t     */\n\t\t    @Override\n\t\t    public void notice(String message) {\n\t\t        for (Observer observer : observerList) {\n\t\t            observer.update(message, name);\n\t\t        }\n\t\t    }\n\t\t}\n\t\t\n\t\t\n\t\t/**\n\t\t * 嫌犯大熊\n\t\t */\n\t\tpublic class XianFan2 implements Badass {\n\t\t    /**\n\t\t     * 别称\n\t\t     */\n\t\t    private String name = \"小熊\";\n\t\t    /**\n\t\t     * 定义观察者集合\n\t\t     */\n\t\t    private List\u003cObserver\u003e observerList = new ArrayList\u003cObserver\u003e();\n\t\t\n\t\t    /**\n\t\t     * 增加观察者\n\t\t     *\n\t\t     * @param observer\n\t\t     */\n\t\t    @Override\n\t\t    public void addObserver(Observer observer) {\n\t\t        if (!observerList.contains(observer)) {\n\t\t            observerList.add(observer);\n\t\t        }\n\t\t    }\n\t\t\n\t\t    /**\n\t\t     * 移除观察者\n\t\t     *\n\t\t     * @param observer\n\t\t     */\n\t\t    @Override\n\t\t    public void removeObserver(Observer observer) {\n\t\t        if (observerList.contains(observer)) {\n\t\t            observerList.remove(observer);\n\t\t        }\n\t\t    }\n\t\t\n\t\t    /**\n\t\t     * 通知观察者\n\t\t     *\n\t\t     * @param message\n\t\t     */\n\t\t    @Override\n\t\t    public void notice(String message) {\n\t\t        for (Observer observer : observerList) {\n\t\t            observer.update(message, name);\n\t\t        }\n\t\t    }\n\t\t}\n5. 测试类：Main\n\t\n\t\t/**\n\t\t * 类名称: Main \u003cbr\u003e\n\t\t * 类描述: \u003cbr\u003e\n\t\t *\n\t\t * @author: lin\n\t\t * @date: // 上午:\n\t\t * @company: Demical\n\t\t */\n\t\tpublic class Main {\n\t\t    public static void main(String[] args) {\n\t\t        //定义两个嫌犯\n\t\t        Badass xf1 = new XianFan1();\n\t\t        Badass xf2 = new XianFan2();\n\t\t        //定义三个观察便衣警察\n\t\t        Observer o1 = new Policeman1();\n\t\t        Observer o2 = new Policeman2();\n\t\t        //为嫌犯增加观察便衣\n\t\t        xf1.addObserver(o1);\n\t\t        xf1.addObserver(o2);\n\t\t        xf2.addObserver(o1);\n\t\t        xf2.addObserver(o2);\n\t\t        //定义嫌犯的情况\n\t\t        String message1 = \"光头强的面包到了\";\n\t\t        String message2 = \"光头强要来砍树了\";\n\t\t        xf1.notice(message1);\n\t\t        xf2.notice(message2);\n\t\t    }\n\t\t}\n6. 测试结果\n\t\n\t\t邹宇:大熊那里有新情况：光头强的面包到了\n\t\t周童:大熊那里有新情况：光头强的面包到了\n\t\t邹宇:小熊那里有新情况：光头强要来砍树了\n\t\t周童:小熊那里有新情况：光头强要来砍树了\n### 观察者模式总结\n\n* 针对观察者与被观察者分别定义接口，有利于分别进行扩展\n* 重点就在被观察者的实现中：\n\t1. 定义观察者集合，并定义针对集合的添加、删除操作，用于增加、\t\t删除订阅者（观察者）\n\t2. 定义通知方法，用于将新情况通知给观察者用户（订阅者用户）\n\t3. 观察者中需要有个接收被观察者通知的方法。\n\n\n* 观察者模式定义的是一对多的依赖关系，一个被观察者可以拥有多个观察者，并且通过接口对观察者与被观察者进行逻辑解耦，降低二者的直接耦合。\n* 如此这般，想了一番之后，突然发现这种模式与桥接模式有点类似的感觉。桥接模式也是拥有双方，同样是使用接口（抽象类）的方式进行解耦，使双方能够无限扩展而互不影响，其实二者还是有者明显的区别：\n 1. 主要就是使用场景不同，桥接模式主要用于实现抽象与实现的解耦，主要目的也正是如此，为了双方的自由扩展而进行解耦，这是一种多对多的场景。观察者模式侧重于另一方面的解耦，侧重于监听方面，侧重于一对多的情况，侧重于一方发生情况，多方能获得这个情况的场景。\n\n 2. 另一方面就是编码方面的不同，在观察者模式中存在许多独有的内容，如观察者集合的操作，通知的发送与接收，而在桥接模式中只是简单的接口引用。\n \n下期说说桥接模式，哈哈。","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flouloulin%2Fzed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flouloulin%2Fzed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flouloulin%2Fzed/lists"}