一、什么是设计模式
设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结.
二、设计模式的作用
使用设计模块是为了重用代码、让代码更容易被他人理解,保证代码可靠性
三、常见的设计模式
常见的设计模型有23中
3.1单例模式
单类模式—-保证一个类仅有一个实例
当类频繁地创建与销毁的时候,我们使用单例模式,这样可以减少了内存的开销,避免对资源的多重占用
单例模式条件:
1.构造方法私有
2.提供一个静态方法【公共】返回创建好的当前类对象
两种表示方式:
1.懒汉式
例如:package com.wangxing.test1; /* * 懒汉式 */ public class lanhan { //创建构造方法 public lanhan(){} //先创建好lanhan对象 private static lanhan obj=null; //创建过得lanhan类对象的方法,避免每次创建出新的对象减少内存的开销 public static lanhan getlanhanClass(){ if (obj==null) { obj=new lanhan(); } return obj; } }
2.饿汉式
例如:package com.wangxing.test1; /* * 饿汉式 */ public class ehan { //创建构造方法 public ehan(){} //提前创建好ehan对象 private static ehan obj=new ehan(); //创建得到饿汉对象的方法 public synchronized static ehan getehanClass(){ return obj; } }
懒汉式与饿汉式的区别
相同点:保证当前类的对象只有一个
书写上:
1.构造方法私有
2.提供一个静态方法【公共】返回创建好的当前类对象
不同点:
书写上:懒汉式中保存当前类的对象变量初始为null,
饿汉式中保存当前类的对象变量初始为new好的当前类对象
运行速度上:懒汉式比饿汉式稍微差一些。
资源利用率:饿汉式比懒汉式稍微差一些。
3.2工厂模式
工厂模式—有一个专门的Java类充当生产对象的工厂
使用工厂模式的条件:
1.需求量大
2.牵一发,动全身
工厂模式中的角色:
工厂角色—生产对象
抽象产品对象—–【抽象/接口】
具体产品——【抽象类/接口类】
例如:有农场各种水果,有西瓜。苹果,香蕉等
工厂角色—–农厂
抽象产品角色—–水果
西瓜、苹果、香蕉—-具体产品
1. 先创建抽象产品的共同功能接口package com.wangxing.test2; public interface ShuiGuo { void eat(); }
2.创建每个具体的水果的类继承功能
package com.wangxing.test2; public class PingGuo implements ShuiGuo{ @Override public void eat() { System.out.println("我是苹果,需要清洗以后吃!!!"); } }
package com.wangxing.test2; public class xigua implements shuiguo{ @Override public void eat() { System.out.println("我是西瓜,切开吃"); } }
3.创建农场的用户选择水果是系统菜单,根据菜单得到某个水果对应的反射对象去创建实例对象
menu.txt
苹果=com.wangxing.test2.pingguo
西瓜=com.wangxing.test2.xigua
4.创建农厂类实现工厂模式package com.wangxing.test2; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.HashMap; /** * * @author Administrator * */ public class NongChang { public static ShuiGuo createShuiGuo(String name){ ShuiGuo sg=null; //读取菜单 HashMap<String,String> menuMap=readMenu(); String className=menuMap.get(name); try{ //利用反射机制创建对象 Class classobj=Class.forName(className); sg=(ShuiGuo)classobj.newInstance(); }catch(Exception e){ e.printStackTrace(); } return sg; } /** * 读取菜单 */ private static HashMap<String,String> readMenu() { HashMap<String,String> menuMap=new HashMap<String,String>(); try{ BufferedReader read=new BufferedReader(new FileReader(new File("menu.txt"))); String menuitem=null; while((menuitem=read.readLine())!=null){ //苹果=com.wangxing.test2.PingGuo String menuarray[]=menuitem.split("="); menuMap.put(menuarray[0],menuarray[1]); } read.close(); }catch(Exception e){ } return menuMap; } }
5.创建测试类
package com.wangxing.test2; import java.io.BufferedReader; import java.io.InputStreamReader; public class TestMain { public static void main(String[] args) throws Exception{ BufferedReader read=new BufferedReader(new InputStreamReader(System.in)); System.out.println("请输入需要的水果:"); String name=read.readLine(); ShuiGuo pg=NongChang.createShuiGuo(name); pg.eat(); } }
这时我们不需要通过得到用户的需求判断再去每次new水果对象,而是交给工厂自己去创建实例对象得到具体东西。避免了重复代码书写。
3.3代理模式
代理模式—-为其他对象提供一种代理以控制对这个对象的访问
买火车票不一定在火车站买,也可以在代售点
代理模式被分为静态代理和动态代理
静态代理有被分为兄弟模式和父子模式
缺点:需要额外提供业务功能实现相似的子类【工作量大】
兄弟模式-—同一个接口的两个子类
例如:
1.创建一个火车站和代售点有共同功能的接口package com.wangxing.test3; public interface SellPiao { void maiPiao(); }
2.让火车站和代售点继承这个接口
package com.wangxing.test3; public class huoCheZhan implements SellPiao{ @Override public void maiPiao() { System.out.println("我是火车票,在火车站买票中"); } }
package com.wangxing.test3; public class daiShouDian implements SellPiao{ @Override public void maiPiao() { System.out.println("我是代售点,在买票中"); } }
3.测试
package com.wangxing.test3; public class Main { public static void main(String[] args) { huoCheZhan hcz=new huoCheZhan(); hcz.maiPiao(); daiShouDian dsd=new daiShouDian(); dsd.maiPiao(); } }
父子模式—继承关系
1.创建一个父类package com.wangxing.test4; public class huoCheZhan { public void maipiao(){ System.out.println("我是火车站,正在卖票"); } }
2.创建一个子类继承父类重写卖票的方法
package com.wangxing.test4; public class daiShouDian extends huoCheZhan{ public void maipiao(){ System.out.println("我是代售点,正在卖票"); } }
3.测试
package com.wangxing.test4; public class Main { public static void main(String[] args) { huoCheZhan hc=new huoCheZhan(); hc.maipiao(); daiShouDian ds=new daiShouDian(); ds.maipiao(); } }
动态代理—由一个java类来负责创建代理类的对象
JDK动态代理—-通过java.lang.reflect包 Class Proxy类来创建代理类对象
【只能为实现过某个接口的java类提供代理类对象】
例如:
1..创建接口package com.wangxing.test5; public interface SellPiao { void maipiao(); }
2.创建继承接口的类
package com.wangxing.test5; public class huoCheZhan implements SellPiao{ @Override public void maipiao(){ System.out.println("我是火车站,正在卖票"); } }
3.创建动态代理,通过实现接口的类得到反射对象从而得到接口子类继承接口的方法,直接创建新的对象但是使用的还是接口子类的方法
package com.wangxing.test5; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyObject implements InvocationHandler{ //定义目标对象 private Object targetObject; public ProxyObject(Object targetObject){ this.targetObject=targetObject; } //得到代理对象 public Object getProxy() { //java.lang.reflect包 Class Proxy类 //ClassLoader loader--类加载器 ClassLoader loader=this.getClass().getClassLoader(); //Class<?>[] interfaces---接口的反射对象 Class[] interfaces=this.targetObject.getClass().getInterfaces(); //InvocationHandler h---this return Proxy.newProxyInstance(loader, interfaces, this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(targetObject, args); } }
package com.wangxing.test5; public class Main { public static void main(String[] args) { huoCheZhan hcz=new huoCheZhan(); hcz.maipiao(); ProxyObject proxyobj=new ProxyObject(hcz); //代理类对象 SellPiao dsd=(SellPiao) proxyobj.getProxy(); dsd.maipiao(); } }
CGlib代理——-CGlib是一个第三发的开发包,用的时候需要自己事先下载导入到项目中
【所有的java类提供代理类对象】
例如:
1.创建需要代理的类package com.wangxing.test6; public class huoCheZhan{ public void maipiao(){ System.out.println("我是火车站,正在卖票"); } }
2.创建获得代理对象
package com.wangxing.test6; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class ProxyObject implements MethodInterceptor{ //定义目标对象 private Object targetObject; public ProxyObject(Object targetObject){ this.targetObject=targetObject; } //得到代理对象 public Object getProxy() { Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(targetObject.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object proxy, Method arg1, Object[] params, MethodProxy methodProxy) throws Throwable { return methodProxy.invokeSuper(proxy, params); } }
3.测试
package com.wangxing.test6; public class Main { public static void main(String[] args) { huoCheZhan hcz=new huoCheZhan(); ProxyObject proxyobj=new ProxyObject(hcz); //代理类对象 huoCheZhan daili=(huoCheZhan) proxyobj.getProxy(); daili.maipiao(); } }
比较:
1.静态代理是通过在代码中显式定义一个业务实现类一个代理,在代理类中对同名的业务方法进行包装,用户通过代理类调用被包装过的业务方法;
手动创建一个与目标类相同接口的子类,包装目标类。
2.JDK动态代理是通过接口中的方法名,在动态生成的代理类中调用业务实现类的同名方法;【兄弟模式】
通过jdk提供的反射包中Proxy这个类,动态的创建一个与目标类实现相同接口的子类对象,包装目标。
3.CGlib动态代理是通过继承业务类,生成的动态代理类是业务类的子类,通过重写业务方法进行代理。【父子模式】
通过CGlib提供的Enhancer这个类,动态的创建一个目标类的子类对象,包装目标类。
静态代理 JDK动态代理 CGlib动态代理 手动创建代理类 动态生成代理类对象 动态生成代理类对象 jdk提供的反射包中Proxy这个类 CGlib提供的Enhancer这个类 只能为实现过接口的Java类创建代理对象 为任何Java类创建代理对象
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/79824.html