zoukankan      html  css  js  c++  java
  • 【设计模式】java设计模式总述及观察者模式

    今天在准备腾讯的面试时想起来要复习一下设计模式,而刚好前几天在参加网易的在线考试的时候,也出了一道关于设计模式的选择题,主要是考察观察者模式,虽然那道题自己做对了,但觉得还是应该好好总结一下设计模式的内容。

    一、设计模式的分类

    总体来说设计模式分为三大类:

    创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

    结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

    行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。


    二、设计模式的六大原则

    1、开闭原则(Open Close Principle)

    开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。


    2、里氏代换原则(Liskov Substitution Principle)

    里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。


    3、依赖倒转原则(Dependence Inversion Principle)

    这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。

    4、接口隔离原则(Interface Segregation Principle)

    这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。

    5、迪米特法则(最少知道原则)(Demeter Principle)

    最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

    6、合成复用原则(Composite Reuse Principle)

    原则是尽量使用合成/聚合的方式,而不是使用继承。


    三观察者模式


    1 概述:

    观察者模式(又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式),观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己,此种模式通常被用来实现事件处理系统,如java和安卓中的监听器。

    2举例:

    观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知自动刷新。

    3模式结构:

    观察者模式的结构中包括四种角色:
     主题(Subject)
     观察者(Observer) 
     具体主题(ConcreteSubject) 
     具体观察者(ConcreteObserver)

    4观察者模式的UML类图:



    5观察者模式代码结构:(节选自百度百科)

    //抽象的观察者,需要用到观察者模式的类需实现此接口
    public interface Observer{
        void update(Object...objs);
    }
     
    //抽象的被观察者
    public abstract class Observable{
     
        public final ArrayList<Class<?>> obserList = new ArrayList<Class<?>>();
     
        /**AttachObserver(通过实例注册观察者)
        *<b>Notice:</b>obcan'tbenull,oritwillthrowNullPointerException
        **/
        public<T> void registerObserver(Tob){
            if(ob==null) throw new NullPointerException();
            this.registerObserver(ob.getClass());
        }
     
        /**
        *AttachObserver(通过Class注册观察者)
        *@paramcls
        */
        public void registerObserver(Class<?>cls){
            if(cls==null) throw new NullPointerException();
            synchronized(obserList){
                if(!obserList.contains(cls)){
                    obserList.add(cls);
                }
            }
        }
     
        /**UnattachObserver(注销观察者)
        *<b>Notice:</b>
        *<b>ItreverseswithattachObserver()method</b>
        **/
        public<T>void unRegisterObserver(Tob){
            if(ob==null) throw new NullPointerException();
            this.unRegisterObserver(ob.getClass());
        }
     
        /**UnattachObserver(注销观察者,有时候在未获取到实例使用)
        *<b>Notice:</b>
        *<b>ItreverseswithattachObserver()method</b>
        **/
        public void unRegisterObserver(Class<?>cls){
            if(cls==null) throw new NullPointerException();
            synchronized(obserList){
                Iterator<Class<?>>iterator=obserList.iterator();
                while(iterator.hasNext()){
                    if(iterator.next().getName().equals(cls.getName())){
                        iterator.remove();
                        break;
                    }
                }
            }
        }
     
        /**detachallobservers*/
        public void unRegisterAll(){
            synchronized(obserList){
                obserList.clear();
            }
        }
     
        /**Ruturnthesizeofobservers*/
        public int countObservers(){
            synchronized(obserList){
                returnobserList.size();
            }
        }
     
        /**
        *notify all observer(通知所有观察者,在子类中实现)
        *@paramobjs
        */
        public abstract void notifyObservers(Object... objs);
     
        /**
        *notify one certain observer(通知某一个确定的观察者)
        *@paramcls
        *@paramobjs
        */
        public abstract void notifyObserver(Class<?> cls, Object... objs);
     
        /**
        *notifyonecertainobserver
        *@paramcls
        *@paramobjs
        */
        public abstract<T> void notifyObserver(T t, Object... objs);
    }
     
    //目标被观察者
    public class ConcreteObservable extends Observable{
     
        private static ConcreteObservableinstance = null;
        private ConcreteObservable(){};
        public static synchronized ConcreteObservablegetInstance(){
            if(instance == null){
                instance=newConcreteObservable();
            }
            returninstance;
        }
     
        @Override
        public <T> void notifyObserver(T t, Object... objs){
            if(t == null) throw new NullPointerException();
            this.notifyObserver(t.getClass(), objs);
        }
     
        @Override
        public void notifyObservers(Object... objs){
            for(Class<?>cls : obserList){
                this.notifyObserver(cls, objs);
            }
        }
     
     
        //通过java反射机制实现调用
        @Override
        public void notifyObserver(Class<?>cls, Object...objs){
            if(cls == null) throw new NullPointerException();
            Method[] methods = cls.getDeclaredMethods();
            for(Method method : methods){
                if(method.getName().equals("update")){
                    try{
                        method.invoke(cls,objs);
                        break;
                    }catch(IllegalArgumentException e){
                        e.printStackTrace();
                    }catch(IllegalAccessException e){
                        e.printStackTrace();
                    }catch(InvocationTargetException e){
                        e.printStackTrace();
                    }
                }
            }
        }
    }
     
    //使用(实现Observer接口)
    public class Text extends Activity implements Observer{
        publicvoidonCreate(...){
            ConcreteObservable.getInstance().registerObserver(Text.class);
            ....
        }
     
        public void update(Object...objs){
            //做操作,如更新数据,更新UI等
        }
    }



  • 相关阅读:
    关于jQuery的两对小括号()()的说明
    高效能 DBA 的七个习惯
    Div+CSS网站设计的优点
    .Net上传图片按比例自动缩小或放大
    SEO草根技术基础—DIV+CSS
    asp.net连接Mysql(connector/net 5.0)
    大型网站(高访问、海量数据)技术架构
    ISO Latin1字符集
    CuteEditor学习总结技巧
    Craigslist 的数据库架构
  • 原文地址:https://www.cnblogs.com/hainange/p/6334056.html
Copyright © 2011-2022 走看看