创建型模式:
单例模式:
保证一个类只有一个实例,并且提供一个访问改实例的全局访问点
减少了系统性能开销,产生一个对象,永久驻留内存
饿汉式:
public class SingletonDemo1{
privatestatic SingletoDemo1=new SingletoDemo1();
privateSingletoDemo1(){}//私有化构造器
publicstatic SingletoDemo1 getInstance(){
returninstance:
}
}//静态加载私有化,公共接口,线程安全,立即加载,不能延时加载。(有可能没有使用过这个实例而浪费资源)
懒汉式:
public class SingletoDemo1{
privatestatic SingletoDemo1 s;
privateSingletoDemo1(){};
publicstatic synchronized SingletoDemo1 getInstance(){
if(s==null){
s=newSingletoDemo1();
}
returns;
}
}//延时加载,资源利用率高,但是每次getinstance()方法都要同步,并发效率低
静态内部类实现方式:(延时加载->使用时才会生成对象+线程安全)
public class SingletoDemo4{
privatestatic class SingletonClassIntance{
privatestatic final SingletoDemo4 instance =new SingletoDemo4();
}
publicstatic SingletoDemo4 getInstance(){
returnSingletonClassIntance.instance;
}
privateSingletoDemo4(){}
}
枚举实现单例:(略,可以防止反射,反序列化
工厂设计模式
实现了创建者和调用者的分离,对于调用者简单
单个产品
class interface Car{
voidrun();
}
简单工厂模式:常用,但对于曾经新产品无能为力,不修改代码的话,是无法扩展的
创建者
public class CarFactory{
publicstatic Car createCar (String type){
if("奥迪".equals(type){
returnnew Audi();
}elseif("比亚迪".equals(type)){
returnnew Byd();
}else
}
}
调用者
public class Client{
publicstatic void main(String[] args){
Carc1=CarFactory.createCar("奥迪");
Carc1=CarFactory.createCar("比亚迪");
c1.run();
c2.run();
}
)
工厂方法模式:增加新的类,可扩展,可是工厂类很多
public interface CarFactory{
CarcreateCar();
}
public class AudiFactory implementCarFactory{
@override
publicCar createCar(){
returnnew Audi();
}
}
//同bydfactory
public class client{
publicstatic void main(String[] args){
Carc1=new AudiFactory().createCar();
Carc2=new bydFactory().createCar();
c1.run();
c2.run();
}
}
抽象工厂模式:
用来生产不同产品组(高,中,低端)的全部产品(如高端汽车的轮胎,发动机。等等一套)
发动机:
public interface Engine{
voidrun();
voidstart();
}
class LuxuryEngine implement Engine{
@override
publicvoid run(){
...
}
publicvoid start(){
...
}
}
class LowerEngine implement Engine{
@override
publicvoid run(){
...
}
publicvoid start(){
...
}
}
轮胎:
public interface Tyre{
voidresolve();
}
class LuxuryTyre implement Tyre{
@override
publicvoid resolve(){
...
}
}
class LowerTyre implement Tyre{
@override
publicvoid resolve(){
...
}
}
汽车工厂
public interface CarFactory{
EnginecreateEngine();
TyrecreateTyre();
}
高端汽车工厂
class LuxuryCarFactory implementCarFactory{
@override
publicEngine createEngine(){
returnnew LuxuryEngine();
}
@override
publicTyre createTyre(){
returnnew LuxuryTyre();
}
}
低端汽车工厂
...
public class Client{
CarFactoryfactory=new LuxuryCarFactory();
Enginee=factory.createEngine();//高端engine
e.run();
e.start();
}
建造者模式
分离了对象子组件的单独构造(由builder来负责)和装配(由director负责)从而构造出复杂的对象
适用于:某个对象的构造复杂的情况下使用。
实现了构造和装配的解耦,不同的构造器,相同的装配,也可以做出不同的对象
相同的构造器,不同的装配顺序,也可以做出不同的对象,也就是实现了构建算法,装配算法的解耦,实现了更好的复用
零件:
class Engine{
privateString name;
构造器+set+get方法;
}
class EscapeTower{
privateString name;
构造器+set+get方法;
}
实体:
public class AirShip{
privateEngine engine;
privateEscapeTower escapeTower;
构造器+set+get方法;
publicvoid launch(){
....
}
}
建造零件:
public interface AirShipBuilder{
EnginebuilderEngine();
EscapeTowerbuilderEscapeTower();
}
组装零件成飞船对象:
public interface AirShipDirector{
AirShipcreateAirShip();
}
实现建造类
public class SxtShipBuilder implementAirShipBuilder{
实现方法,new 各种零件;
}
public class SxtAirShipDirector implementAirShipDirector{
piravateAirShipBuilder builder;
构造器;
publicAirShip direcAirShip(){
//构建子组件
Enginee=builder.builderEngine;
EscapeToweret=builer.builderEscapeTower;
//组装
AirShipship=new AirShip();
ship.setEngine(e);
ship.setEscapeTower(et);
returnship;
}
}
public class Client{
publicstatic void main(String[] args){
AirShipDirectordirector=new SxtAirShipDirector(new SxtShipBuilder());//组装者得到建造的零件
AirShipship =director.direcAirShip();//建造飞船
ship.launch();//飞船发射
}
}
原型模式:(prototype克隆模式)
cloneable接口(标记)和(属于Object)clone方法->调用本地c代码,效率高
困难在于内存复制操作,与new不同在于new是默认值
public class Sheep implementsCloneable{//1997.的多利羊
privateString sname;
privateDate birthday;
protectedObject clone()throws CloneNotSupportedException{
Objectobj=super.clone();调用object的clone方法
//Sheeps=(Sheep)obj;加上这两条代码后
//s.birthday=this.birthday.clone();属性也进行克隆,此为深拷贝
returnobj;
}
setget方法;
}
//浅克隆
public class client{
publicstatic void main(args[])throws Exception{
Sheeps1=new Sheep("多利",new Date(1234654654));
System.out.println(s1);
Sheeps2=(Sheep)s1.clone();
System.out.println(s2);
//s1=s2,s1和s2是完全相同的两个对象,克隆,但s1和s2共同使用同一个date,String对象也是同一个!
注意String类是不可变字符串,所以用stringbuffer进行证明
如果数据有基本数据类型,int,double,那么拷贝出来的是不同的!(此为浅拷贝)
}
}
方法二:利用序列化和反序列化实现深克隆
public class client{
publicstatic void main(args[])throws Exception{
Datedate=new Date(1234564);
Sheeps1=new Sheep("多利",date);
System.out.println(s1);
//序列化
ByteArrayOutputStreambos=new ByteArrayOutputStream();
ObjectOutputStreamoos=new ObjectOutputStream(bos);
oos.writeObject(s1);
byte[]bytes=bos.toByteArray();
//反序列化
ByteArrayInputStreambis=new ByteArrayInputStream(bytes);
ObjectInputStreamois=new ObjectInputStream(bis);
Sheeps2=(Sheep)ois.readObject();
}
}//Sheep类要实现serializable接口
结构型模型:
适配器模式
将一个类的接口转换成客户希望的另外一个接口。
适配器通过使用属性调用适配对象的方法,通过实现(继承)了Target接口,使得可以用父类Target接口类来接收适配器,之后Client只需要跟传入Target(即适配器)打交道
用途:旧系统改造和升级
如果我们的系统开发之后再也不需要维护,那么很多模式都是没必要的,但是不幸的是,事实却是维护一个系统的代价往往是开发一个系统的数倍。
应用:
java.io.InputStreamReader(InputStream)
java.io.OutputStreamWriter(OutputStream)
android:listview,viewpager
笔记本:
public class Client(){
publicvoid test1(Target t){
t.handleReq();
}//通过适配器,调用了键盘的功能
publicstatic void main(String[] args){
Clientc=new Client();//笔记本
Adapteea=new Adaptee();//被适配的对象->键盘
//Targett=new Adapter();方法一
//Targett=new Adapater2(a);方法二
c.test11(t);
}
}
目标接口:
public interface Target{
voidhandleReq();
}
被适配的类:(键盘)
public class Adaptee{
publicvoid request(){System.out.println("可以完成客户请求需要的功能")};//打字的功能
}
适配器:(PS/2,USB的转接器)
-------类适配器的方式,继承
public class Adapter extends Adapteeimplements Target{
@override
publicvoid handleReq(){
super.request();
}
}
-------对象适配器方式,组合(更灵活)
public class Adapter2 implements Target{
privateAdaptee adaptee;
@override
publicvoid handleReq(){
adaptee.request();调用得到的键盘的发送请求方法来重写了接口中的发送请求的方法,此时,键盘的拥有的方法和笔记本能接口的方法相同,适配成功
}
publicAdapter(Adaptee adaptee){
super();
this.adaptee=adaptee;//得到一个键盘
}
}
代理模式(Proxy pattern)
核心作用:
通过代理,控制对对象的访问,可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理(从而实现将统一流程代码放到代理类中处理),调用这个方法后做后置处理(即AOP的微观实现)
AOP(Aspect OrientedProgramming面向切面编程)的核心实现机制.
反客为主,代理控制真实
真实角色:JAY,关注真正业务逻辑
代理角色:经纪人,将统一的流程控制放到代理角色中处理
抽象角色:遵守共同的抽象接口,共同点。
客户:调用抽象角色
安全代理:屏蔽对真实角色的直接访问
远程代理:通过代理类处理远程方法调用(RMI)
延时加载:先加载轻量级的代理对象,真正需要再加载真实对象。
分类:
静态代理(静态定义代理类,自己定义)
动态代理(动态生成代理类,程序自动生成)
JDK自带的动态代理
javaassist字节码操作库实现
CGLIB
ASM(底层使用指令,可维护性较差)
public interface Star{
voidconfer();面谈
voidsignContract();签合同
voidbookTicket();订票
voidsing();唱歌--JAY
voidcollectMoney();收钱
}//抽象角色
public class RealStar implements Star{
实现所有方法
}
public class ProxyStar implements Star{
privateStar star;//可以同时代理很多个对象
publicProxyStar(Star star)
{
super();
this.star=star;
}
实现所有方法除了 voidsing();
publicvoid sing(){
star.sing();
}
}
public class Client{
publicstatic void main(String[] args){
Starreal=new RealStar();
Starproxy=new ProxyStar();
proxy.confer();调用的是代理的方法
....
proxy.sing();---实际使用的是真实类的方法,但是用户并不知道
}
}
动态代理(dynamic proxy)
代理内容动态生成
java.lang.reflect.Proxy动态生成代理类和对象
java.lang.reflect.InvocationHandler处理器接口
可以通过invoke方法实现对真实角色的代理访问
每次通过Proxy生成代理类对象时都要制定对应的处理器对象
Star接口和RealStar实现类与静态相同
public class StartHandler implementsInvocationHandler{
Starrealstar;
publicStarHandler(Star realStar){
super();
this.realstar=realstar;
}
调用方法这里这里集中,这里进行统一流程控制:
@override
publicObject invoke(Object proxy,Method,Object[] args){
throwsThrowable{
Objectobject=null;
System.out.println("唱歌之前");
if(method.getName().equals("sing")){
object=method.invoke(realStar,args);//调用realstar的方法
}
System.out.println("唱歌之后");
returnobject;
}
}
}
public class Client{
publicstatic void main(String[] args){
StarrealStar=new RealStar();
StarHandlerhandler=new StarHandler(realStar);
Starproxy=(Star)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),newClass[](Star,class),handler);
proxy.sing();//调用真实类
}
}
网友评论