【设计模式】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类图:

【设计模式】java设计模式总述及观察者模式



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等
    }
}



上一篇:题解西电OJ (Problem 1004 -亚特兰提斯)--最小生成树


下一篇:《深入浅出Node.js》学习笔记(一)