Java设计模式

来源:互联网 发布:网络修复器 编辑:程序博客网 时间:2024/06/05 07:58

抽象类和接口的区别

1.      抽象类可以有自己的数据成员,但是接口只能有静态不能被修改的数据成员(要给定初值,且一般不这么做)

2.      抽象类只能继承一次,但是接口可以实现多次

3.      抽象类可以有默认的行为,但是接口不能(除非用委托)

 

 

 

策略模式:定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户.

 

策略就是把所有的行为可以策略性的改变,并且在以后可以根据需要做最小的修改就完成需求,就是行为可以在特定的需求的时候实现该行为接口,实现方式为指定行为类

例如Duck例子,算法族就是指各种不同鸣叫和飞行方法,根据不同的鸭子来定制算法,不过这个算法封装进一个类,如果需要改变算法可以用setter改变.通过在基类上运用实例变量(声明是一个接口类)那么就可以可以通过实现不同的实例来实现不同的算法,例如鸣叫方式

 

 

面向对象原则:多用组合,少用继承

针对接口编程,不针对实现编程

 

 

 

 

观测者模式是主题通过一个Subject接口来实现注册,移除,发布消息函数来,Subject中注册,移除函数参数为观察者,观察者要实现一个Observer接口(要实现数据传递如updata函数以及传递相应参数).主题要维护一个观察者的列表(用于发布消息),通过注册的观察者(参数为接口类)来实现动态拔插.

 

Java实现的Observer不需要自己维护观察者对象,在调用notify之前要setchange因为需要更新,如果在主题实现getter的话就可以在观察者那实现拉方式获得数据因为观察者更新是通过一个主题对象参数来操作的

public voidupdate(Observable obs,Object arg){

        if(obsinstanceof WeatherData){

            WeatherDataweatherData = (WeatherData)obs;

            this.temperature =weatherData.getTemperature();

            this.humidity =weatherData.getHumidity();//所以主题要实现getter

            display();

        }

    }

例如java事件响应就是运用了观察者模式

 

面向对象原则:

为交互对象之间的松耦合设计而努力,这样以后维护的时候可以做到最小修改

 

观察者模式定义:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新,因为在notify中已经有了那个引用,然后在update过去

使用观察者模式,会改变的是主题的状态,以及观察者的数目和类型,用这个模式可以改变依赖于主题状态的对象而不用改变主题.需要实时通知状态的功能等

 

设计原则:

类应该对扩展开放,对修改关闭

 

 

 

装饰者可以再所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的

 

装饰者模式:动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案

 

装饰者模式是使用个虚基类来保存描述信息,然后在装饰者中继承此类,其中要有一个基础的类(被装饰者)然后在这个基础上装饰,装饰者也要实现一个虚基类,并且在构造函数中的参数中得到被装饰者,然后在被装饰者的信息基础上加上装饰者的信息,根据具体功能来设置那个虚基类

 

 

工厂方法模式:定义了一个创建对象的接口,但由子类确定要实例化的类是哪一个.工厂方法让类把实例化推迟到子类

 

在设计模式中,”实现一个接口”泛指实现某个超类型(可以是类或接口)的某个方法

 

简单工厂吧全部的事情,在一个地方都处理完了,然而工厂方法却是创建一个框架,让子类确定如何实现,比方说,在工厂方法中,orderPizza()方法提供了一般的框架,以便创建比萨,orderPizza()方法依赖工厂方法创建具体类,并制造出实际的比萨.可通过继承PizzaStore类,决定实际制造出的比萨是什么.简单工厂的做法,可以将对象的创建封装起来,但是简单工厂不具备工厂方法的弹性,因为简单工厂不能变更正在创建的产品.例如增加另外一些州口味的比萨(需要改代码),而不是通过新建一个州口味的PizzaStore来实现

 

 

依赖倒置设计原则:

要依赖抽象,不要依赖具体类

 

这个原则像是,”|针对接口编程,不针对实现编程”,然后这里更强调”抽象”.这个原则说明了,不能让高层组件依赖底层组件,而且不管高层或底层组件,”两者”都应该依赖于抽象

例如PizzaStore为高层组件,而具体Pizza为底层组件,如果吧创建各类Pizza在PizzaStore中决定,那么高层组件就依赖底层组件了,那么只要底层组件改变,那么高层组件也可能必须改变

所谓的倒置就是指现在高层组件(PizzaStore)和底层组件(具体的Pizza)都依赖于Pizza这个抽象类.依赖图倒置了,因为底层组件现在竟然是依赖于高层的抽象了

依赖倒置原则用可以用一下几个方针来避免违反该原则:

变量不可以持有具体类的引用

       如果使用new,就会持有具体类的引用,你可以改用工厂来避开这样的做法

不要让类派生自具体类

       如果派生自具体类,你就会依赖具体类,请派生自一个抽象(接口或抽象类)

不要覆盖基类中已经实现的方法

       如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被继承的抽象.基类中已经实现的方法,应该由所有子类共享

以上方针并不是一定要遵守.例如一个不需要改变的类就可以不遵守

 

 

 

抽象工厂模式:

提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类

 

抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道(或关心)实际产出的具体产品是什么,这样一来,客户就从具体的产品中被解耦

 

 

 

抽象工厂模式就是在工厂方法模式基础上再抽象多一层,其实就是用工厂方法模式来实现具体类.

例如:客户选择去哪家店,然后给出字符串实例化哪种pizza

 

工厂方法模式是客户决定具体化什么具体类,就是客户自己选择具体类(PizzaStore)(通过子类具体化)

抽象工厂模式是通过对象组合来实现.在工厂方法模式基础上用对象组合(家族)来实现具体类,选择了PizzaStore后用对象组合来实现不同配料表,在Pizza上保存各种配料的抽象,然后在具体类上实现具体的配料.类同策略模式,但是可变更的组合变多,就是在Pizza上保存的抽象类增多

 

单例模式:确保类只有一个实例,并提供全局访问点

 

 

用Sychronized实现双重检查加锁

 

 

 

 

命令模式:将”请求”封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象.命令模式也支持可撤销的操作

 

 

可以实现一个同级的什么都不做的对象来当做空操作,或者是默认操作也可以

 

 

 

 

抽象很重要!!!!!!!!抽象程度越高就扩展度越大

 

命令模式可以用于事务系统;日志恢复,故障恢复等,通过在command接口上定义store(),load()

 

命令模式就是通过一个中介来操作各种不同厂商实现的api再在这个基础上继承command接口实现各种厂商不同api的中介类,然后通过遥控器中介类去操作不同厂商实现command类的中介类

 

 

 

 

适配器模式,例如要适配A,B类.那么创建一个适配器类继承B类,并创建一个A类实例变量,通过实现B类的接口,吧A类相似的行为改变为B类就完成

 

 

适配器模式:

将一个类的接口,转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间.

 

“类”适配器需要多重继承才能实现.但是对象适配器只需要对象组合就可以了(然后通过委托来实现).

在适配器模式中如果出现被适配接口没有但是目标接口有的操作,那么需要抛出异常UnsupportedOpeartionException

 

 

 

外观模式是通过将一个或数个类的复杂的一切都隐藏在背后,只显露出一个干净美好的外观,就是通过简化接口来实现.

外观模式定义:提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用

 

 

外观模式和适配器模式的差异不在于他们”包装”了几个类,而是在于他们的意图.适配器模式的意图是”改变”接口符合客户的期望;而外观模式的意图是,提供子系统的一个简化接口

 

 

最少知识原则:只和你的密友谈话

就是说减少对象之间的交互,只留下几个”密友”

 

外观模式就是把几个类需要协同合作的任务封装到一个类里面,并且提供一个简单的接口来实现.就是把复制的类调用和组合变成一个简单接口

 

 

 

模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤

 

模板方法就是一个方法,这个方法将算法定义为一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现.这个可以确保算法的结构不变,同时由子类提供部分实现

 

钩子就是一个函数,在基类上声明(抽象方法或者默认实现).这样就可以改变抽象类(基类)的算法流程

 

可选的步骤可以实现成钩子

 

 

好莱坞原则:

别调用(打电话给)我们,我们会调用(打电话给)你

就是底层组件不能直接调用高层组件,但是高层组件可以调用底层组件,不要形成循环调用,循环依赖

 

依赖倒置原则教我们尽量避免使用具体类,依赖具体类

好莱坞原则教我们一个技巧,创建一个有弹性的设计,允许底层结构能够互相操作,而又防止其他类太过依赖他们

 

 

策略模式和模板方法模式不同的就是一个用组合一个用继承

 

工厂方法是模板方法的一种特殊版本

 

 

将有共同的行为定位为接口

 

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露内部的表示

 

设计原则:一个类应该只有一个引起变化的原因

尽量让每个类保持单一责任

 

内聚(cohesion)这个术语用来度量一个类或模块紧密地达到单一目的或责任

当一个模块或一个类被设计成只支持一组相关的功能时,我们说它具有高内聚;反之,当被设计成一组不相关的功能时,我们说它具有低内聚

 

组合模式:允许你将对象组合成树形结构来表现”整体/部分”层次结构.组合能让用户以一致的方式处理个别对象以及对象组合

就是通过让组件包含操作整体和部分的接口函数,然后整体和部分都继承这个组件

 

组合模式内的任意对象称为组件,组件可以是组合也可以是叶节点

 

 

 

 

状态模式:允许对象在内部状态改变时改变它的行为,对象看起来就好像修改了它的类

其实就是在类保存各个状态的实例变量和当前的实例变量,然后再实现各个行为的函数(里面调用当前状态的相应行为函数)每个行为都要实现一个行为接口,并在里面设置每个状态下的行为所应当做的正确行为.或者转换另外一个状态,所以要在状态类的构造函数保存或者一个上一层的类对象来设置状态,就是类委托给相应状态处理

 

 

状态模式和策略模式的类图是一样的,不过他们之间的区别在于意图

状态模式是根据当前状态和客户的动作去确定各个行为的正确行为(通过传递上层类对象来装换状态)

策略模式是根据客户指定所要的策略对象来选定哪个正确的行为

 

 

 

制作远程服务”

1.制作远程接口

2.制作远程实现

3.利用rmic工具产生的stub和skeleton

4.启动rmi registry

5.开始远程服务

 

 

 

一个接口可以继承多个基类接口

 

RMI其实就是配置好文件后用(class)Name.lookup(rmi://127.0.0.1/RemoteRegistryName);来调用真正对象

 

 

代理模式:为另一个对象提供一个替身或占位符以控制对这个对象的访问

书上描述的有远程代理,保护代理,虚拟代理

 

需要用到代理模式的情况有,远程对象,对象创建的开销大,需要权限控制或被保护对象

 

 

Eclipse /**后输入回车会自动生成相应上面一条函数或者类的注释文档格式的注释

 

 

 

使用组合模式可以直接调用一组同基类的类的方法,通过结合迭代器模式就可以对客户透明的调用一组相同的类,而不管是组合还是叶子节点

 

如果类都有一个同样功能的组件或者类的话那么可以用组合模式通过委托的形式来实现,这样可以做到代码重用,并且设计明确,清晰

 

 

模型:模型持有所有的数据,状态和程序逻辑.模型没有注意到视图和控制器,虽然它提供了操纵和检索状态的接口,并发送状态改变通知给观察者

 

视图:用来呈现模型.视图通常直接从模型中取得它需要显示的状态和数据

 

控制器:取得用户的输入并解读其对模型的意思

 

MVC是复合模式,结合了观察者模式,策略模式和组合模式

 

复合模式:复合模式结合了两个或以上的模式,组成一个解决方案,解决一再发生的一般性问题

 

反模式告诉你如果采用一个不好的解决方案解决一个问题

 

0 0