当前位置: 首页 > news >正文

采集侠 wordpress西安官网优化哪家公司好

采集侠 wordpress,西安官网优化哪家公司好,阿里巴巴上做英文网站一年多少钱,土巴兔装修公司1 前言 1.1 内容概要 理解使用设计模式的目的掌握软件设计的SOLID原则理解单例的思想#xff0c;并且能够设计一个单例理解工厂设计模式的思想#xff0c;能够设计简单工厂#xff0c;理解工厂方法了解建造者模式的思想#xff0c;掌握其代码风格理解代理设计模式的思想并且能够设计一个单例理解工厂设计模式的思想能够设计简单工厂理解工厂方法了解建造者模式的思想掌握其代码风格理解代理设计模式的思想理解动态代理类和委托类目标类之间的关系熟悉代理对象调用方法的执行过程熟练使用动态代理完成代码设计了解责任链设计模式的思想 1.2 前置准备 理解抽象部分为什么使用接口或抽象类在什么情况下使用接口什么情况下使用抽象类 静态内部类的类加载过程 匿名内部类的定义和使用 反射反射过程中的常用名词Class、Field、Method、Parameter、Constructor。反射过程中的常用方法 获得class、field、method、parameter、constructor → getDeclaredXXX通过反射获得实例 class和constructor通过反射调用方法 method.invoke(instance,args) Lombok使用 2 设计模式简介 2.1 什么是设计模式 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。设计模式代表了最佳的实践通常被有经验的软件开发人员所使用。 2.2 设计模式的分类 设计模式共有23种根据用途的不同设计模式可以分为创建型、结构型、行为型三种。 创建型模式 这类模式提供创建对象的机制 能够提升已有代码的灵活性和可复用性。 包括工厂方法Factory Method、抽象工厂Abstract Factory、生成器Builder、单例Singleton、原型prototype。常见的有单例、工厂、建造者(生成器)模式 结构型模式 这类模式介绍如何将对象和类组装成较大的结构 并同时保持结构的灵活和高效。包括适配器Adapter、桥接Bridge、代理Proxy、装饰Decorator、外观Facade、享元Flyweight、组合Composite。常用的有代理、桥接、装饰者、适配器模式。 行为型模式 这类模式负责对象间的高效沟通和职责委派。包括责任链Chain of Responsibility、迭代器Iterator、状态State、观察者Observer、策略Strategy、模板方法Template Method、命令Command、中介者Mediator、备忘录Memento、Visitor访问者。常见的有观察者、模板、策略、责任链、迭代器、状态模式。 2.3 设计模式原则 设计模式需要有设计的原则作为指导纲领设计模式是在设计原则的指引下设计出来的。因为我们需要对设计原则有一个清晰的认识。 设计原则按照字母手写简写可以概括为SOLID原则。 单一职责原则Single Responsibility Principle 开放封闭原则Open Close Principle 里氏替换原则Liskov Substitution Principle 迪米特法则Least Knowledge Principle 接口分离原则Interface Segregation Principle 依赖倒置原则Dependency Inversion Principle 2.3.1 单一职责原则 尽量使得每个类只负责整个软件的功能模块中的一个。当程序不断壮大之后类也会变得非常的庞杂查找某部分代码也会变得非常的吃力如果此时需要做任何一处的修改那么整个类的代码都会受到影响。 2.3.2 开放封闭原则 开闭原则规定软件设计中的对象、类、模块以及函数等对于扩展是开放的但是对于修改是封闭的。如果一个功能模块已经开发、测试完毕那么对其代码直接进行修改便是由很大风险的。如果有新的业务功能那么应当做的事情是对于现有代码进一步扩展而不是修改现有代码。比如可以创建一个子类来重写这部分业务逻辑以到达目的等。也就是说我们应该选择使用抽象来定义结构用具体实现来扩展细节。 上述讨论的前提是代码中没有缺陷等问题如果代码中存在缺陷、bug等那么直接对其进行修复即可。 2.3.3 里氏替换原则 它由芭芭拉·利斯科夫Barbara Liskov在1987年在一次会议上名为“数据的抽象与层次”的演说中首先提出。主要内容如下 如果S是T的子类型对于S类型的任意对象如果将他们看作是T类型的对象则它的行为也理应和预期的行为一致。 这意味着子类必须保持与父类行为的兼容。在重写一个方法时你要对基类行为进行扩展而不是将其完全替换。在使用父类的程序中替换为使用子类那么程序的运行结果应该是一致的不会发生任何异常。 2.3.4 迪米特法则 又叫作最少知道原则指的是一个类/模块对于其他的类/模块有越少的了解越好。简单来说就是不应该有依赖关系的类之间不要存在依赖关系有依赖关系的类之间尽量只依赖于接口。 2.3.5 接口隔离原则 一个类对另外一个类的依赖应当建立在最小的接口上。这句话的含义其实是要为各个类建立它们需要的专用接口而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。 2.3.6 依赖倒置原则 指的是设计代码架构时高层模块不应该依赖于底层模块二者都应该依赖于抽象。抽象不应该依赖于细节细节应该依赖于抽象。其所表达的含义是指在软件设计过程中细节具有多变性而抽象则相对稳定因此以抽象为基础搭建起来的架构要比以细节为基础搭建起来的架构稳定的多。 3 常用设计模式 3.1 创建型模式 创建型模式提供了创建对象的机制能够提升已有代码的灵活性和可复用性。 3.1.1 单例模式Singleton 单例是一种创建型设计模式让你保证一个类只有一个实例对象并提供了一个访问该实例对象的全局节点 。 3.1.1.1 饿汉模式 在类加载的过程中初始化了私有的静态实例对象保证了该实例对象的线程安全性。因为该实例对象先于使用前提供所以称之为饿汉模式。 package com.cskaoyan.pattern.singleton;/*** ClassName Singleton1* Description:* 饿汉式**/ public class Singleton1 {//创建私有静态实例对象private static final Singleton1 instance new Singleton1();//私有化构造函数private Singleton1(){}public static Singleton1 getInstance(){return instance;} }饿汉式特点不支持延时加载懒加载获取对象速度比较快但是如果对象比较大或者一直没有去使用那么比较浪费内存空间。 3.1.1.2 懒汉模式(线程不安全) package com.cskaoyan.pattern.singleton;/*** ClassName Singleton2* Description:* 懒汉式-线程不安全**/ public class Singleton2 {private static Singleton2 instance;//私有化构造函数private Singleton2(){}//判断当前对象是否已经被创建public static Singleton2 getInstance(){if(instance null){instance new Singleton2();}return instance;} }编写测试用例我们使用1000个线程来创建Singleton2对象发现对象的地址不同。产生上述问题的主要原因在于我们执行的代码其实都不是原子性在多线程操作的过程中会进行线程切换。比如线程A执行到 if(instance null){继续执行代码便会创建instance实例对象 但是此时进行了线程切换切换到了线程B线程B创建了instance对象随后再次线程切换给线程A因为线程A已经执行过判断所以便会直接执行instance new Singleton2();便又会创建一个对象。 3.1.1.3 懒汉模式(线程安全) 如何保证线程安全呢使用synchronized关键字即可。 package com.cskaoyan.pattern.singleton;/*** ClassName Singleton3* Description:* 懒汉式-线程安全**/ public class Singleton3 {private static Singleton3 instance;//私有化构造函数private Singleton3(){}//引入synchronized保证多线程模式下实例对象的唯一性public static synchronized Singleton3 getInstance(){if(instance null){instance new Singleton3();}return instance;} }使用synchronized锁住对象创建的方法防止该方法被多个线程同时调用。 但是这种方式最合适吗 因为我们对getInstance()添加了锁降低了该方法的并发量实际上我们只需要针对最开始抢先创建实例对象的线程加锁即可后续的线程在执行时因为if(instance null)条件已经不满足所以直接执行返回实例对象即可此时不需要加锁。 3.1.1.4 双重检查(Double Check) 针对上述存在的问题我们做了进一步修改。这种方式最明显的特征是synchronized关键字不是修饰整个方法而是仅修饰创建对象的代码块可以提高并发此外存在两个if条件判断语句。这也是双重检查的由来。为什么需要双重检查呢线程A可能首先先执行到了外层的if条件判断执行通过之后并没有进一步执行而是进行了线程的切换切换成了线程B线程B也执行了外层的if条件判断并且顺利地获取到了锁执行完了内部的if条件判断创建了实例对象如果此时线程再次切换给线程A线程A因为刚刚已经执行完外层的if条件判断此时顺利的获取到了锁如果没有内部的if条件判断则会再次创建一个实例对象。这也是为何一定要双重检查的原因。 package com.cskaoyan.pattern.singleton;/** * ClassName Singleton4 * Description: * 懒汉式-双重检查 **/ public class Singleton4 {private static Singleton4 instance;//私有化构造函数private Singleton4(){}public static Singleton4 getInstance(){if(instance null){synchronized (Singleton4.class){if(instance null){instance new Singleton4();}}}return instance;} }3.1.1.5 静态内部类 利用静态内部类来解决延迟加载、线程安全的问题并且可以使得代码更加简洁。由JVM来保障线程安全性。 public class Singleton5 {private static Singleton5 instance;//私有化构造函数private Singleton5(){}//静态内部类private static class SingletonHolder{private static Singleton5 instance new Singleton5();}public static Singleton5 getInstance(){return SingletonHolder.instance;} }3.1.1.6 枚举 public enum Singleton6 {INSTANCE;public static Singleton6 getInstance(){return INSTANCE;} }3.1.1.7 总结 饿汉式在类加载时期便已经将instance实例对象创建了所以这种方式是线程安全的方式但是不支持懒加载。懒汉式该种方式支持懒加载但是要么不是线程安全要么虽然是线程安全但是需要频繁释放锁、抢夺锁并发量较低。双重检查既可以实现懒加载又可以实现高并发的需求。这种方式比较完美但是代码有一些复杂。静态内部类使用该种方式也可以解决懒加载以及高并发的问题代码实现起来比双重检查也是比较简洁。枚举最简单、最完美的实现方式。 3.1.2 工厂模式Factory 工厂顾名思义就是生产产品的地方。我们通常会定义工厂类、接口通过该工厂类或其工厂实例提供的方法能够获得返回值该返回值就是通过工厂生产的实例。 也就是说工厂中一定会提供一个返回实例的方法。其中核心的好处是封装隐藏生产的具体细节 工厂类或接口的命名方式通常为XXXFactory 3.1.2.1 简单工厂模式 之所以叫简单工厂是因为真的非常简单只要一个工厂函数就可以了那么只需要传入不同的参数就可以返回不同的产品实例这种模式就叫简单工厂模式。 比如我们要生产Tesla汽车Tesla下又有不同的产品比如Model3、ModelY、ModelS等我们其实可以通过给简单工厂传入不同的参数来生产不同的产品 首先定义不同的产品 public abstract class Tesla {String name;public Tesla(String name) {this.name name;}public void run(){System.out.println(name 在路上跑);} } public class Model3 extends Tesla{public Model3() {super(model 3);} } public class ModelS extends Tesla{public ModelS() {super(model S);} } public class ModelY extends Tesla{public ModelY() {super(model Y);} }我们在上面定义了抽象类Tesla通过不同的子类定义不同的车型 接下来我们首先先不使用工厂 Scanner scanner new Scanner(System.in); String keyword scanner.nextLine(); Tesla tesla null; switch (keyword) {case model3:tesla new Model3();break;case modely:tesla new ModelY();break;case models:tesla new ModelS();break;default:tesla new Tesla(未知车辆) {Overridepublic void run() {System.out.println(name 路上请注意道路千万条安全第一条);}};break; } tesla.run();然后我们再使用工厂 将获得tesla对象的过程放入到工厂的生产方法中故定义一个这样的工厂 public class SimpleTeslaFactory {public static Tesla create(String keyword) {Tesla tesla null;switch (keyword) {case model3:tesla new Model3();break;case modely:tesla new ModelY();break;case models:tesla new ModelS();break;default:tesla new Tesla(未知车辆) {Overridepublic void run() {System.out.println(name 路上请注意道路千万条安全第一条);}};break;}return tesla;} }其中的create方法可以定义为静态 我们通过工厂提供的create方法可以直接获得tesla对象 Scanner scanner new Scanner(System.in); String keyword scanner.nextLine(); Tesla tesla SimpleTeslaFactory.create(keyword); tesla.run();3.1.2.2 工厂方法模式 工厂方法模式是一种创建型设计模式其在父类中提供一个创建对象的方法允许子类决定实例化对象的类型。 它的主要意图是定义一个创建对象的接口让其子类自己决定实例化哪一个工厂类工厂模式使其创建过程延迟到子类进行。 我们模拟客户下单一辆特斯拉电动车特斯拉生产车间需要交付一辆该型号汽车来讲述该设计模式。首先不借助于任何设计模式我们先完成该功能。 import java.util.Scanner;/*** ClassName OrderCar**/ public class OrderCar {public static void main(String[] args) {Scanner scanner new Scanner(System.in);String keyword scanner.nextLine();Tesla tesla SimpleTeslaFactory.create(keyword);tesla.run();} }上述的案例我们便实现了根据订购的车型不同生产不同的车辆。但是面临最大的问题便是在于扩展车型时非常的麻烦。当我们需要重构代码时代码中涉及到的地方千丝万缕、错综复杂会使得开发人员望而却步。接下来我们尝试使用工厂方法来重构上述代码。 对应的类关系如下 public interface TeslaFactory {public Tesla getTesla(); }public class ModelYFactory implements TeslaFactory{Overridepublic Tesla getTesla() {return new ModelY();} } public class Model3Factory implements TeslaFactory{Overridepublic Tesla getTesla() {return new Model3();} } //其他工厂类似就不全部列举了public class OrderTesla {private static MapString, TeslaFactory factoryMap new HashMap();static {factoryMap.put(modelx, new ModelXFactory());factoryMap.put(modely, new ModelYFactory());factoryMap.put(models, new ModelSFactory());factoryMap.put(model3, new Model3Factory());}public static void main(String[] args) {Scanner scanner new Scanner(System.in);String keywords scanner.nextLine();TeslaFactory teslaFactory factoryMap.get(keywords.toLowerCase());Tesla tesla teslaFactory.getTesla();tesla.run();} }通过OrderTesla类的代码和OrderCar代码进行比较我们发现代码明显变得更加简洁了。 3.1.2.3 抽象工厂模式 抽象工厂模式是所有工厂模式中抽象程度最高的一种模式。抽象工厂模式可以向客户端提供一个接口使得客户端可以在不必指定具体类型的情况下能够创建多个一系列或者相关联的对象。 工厂方法和抽象工厂首先都是要将工厂抽象为接口或抽象类。工厂方法主要是生产的是单个产品抽象工厂主要是生产是一系列的产品。 工厂方法单品 抽象工厂产品矩阵 我们以下面这个案例来进行讲述。随着智能家居的兴起许多家庭在选择家居电器时会倾向于选择同一厂家的产品。比如目前市面上有Haier以及Mi的家居产品。不同的厂家产品线都非常丰富涵盖TV、Freezer等。设计一套代码程序根据用户选择的厂家提供对应的配套产品。 对应的类关系如下 public abstract class AbstractFurnitureFactory {public abstract TV createTV();public abstract Freezer createFreezer(); }public class MiFurnitureFactory extends AbstractFurnitureFactory{Overridepublic TV createTV() {return new MiTV();}Overridepublic Freezer createFreezer() {return new MiFreezer();} }public class HaierFurnitureFactory extends AbstractFurnitureFactory{Overridepublic TV createTV() {return new HaierTV();}Overridepublic Freezer createFreezer() {return new HaierFreezer();} }public class OrderFurniture {public static void main(String[] args) {MiFurnitureFactory miFactory new MiFurnitureFactory();TV tv miFactory.createTV();Freezer freezer miFactory.createFreezer();System.out.println(tv instanceof MiTV (tv instanceof MiTV));System.out.println(freezer instanceof MiFreezer (freezer instanceof MiFreezer));} }3.1.3 建造者模式Builder 建造者模式也叫作生成器模式就是分步骤创建复杂对象该模式允许使用相同的创建代码生成不同类型和形式的对象。 在开发中有时候我们需要创建出一个很复杂的对象这个对象的创建有一个固定的步骤并且每个步骤中会涉及到多个组件对象这个时候就可以考虑使用建造者模式。使用建造者模式将原本复杂的对象创建过程按照规律将其分解成多个小步骤这样在构建对象时可以灵活的选择或修改步骤。建造者模式将对象的创建和表示过程进行分离这样我们可以使用同样的过程只需修改这个过程中的小步骤便能够构建出不同的对象。而对于调用方来说我们只需要传入需要构建的类型便能够得到需要的对象并不需要关系创建的过程从而实现解耦。 比如我们要制造手机手机里包含屏幕、颜色、电池、摄像头、系统等组成那么我们定义一个Phone如下 Data public class Phone {private String battery;private String screen;private String os;private String camera;private String color;// 通过Data提供了getter/setter方法以及我们打印的时候用的toString方法 }然后我们要提供一个PhoneBuilder类 通过Builder类提供的build方法能够获得Phone实例同时提供一些方法通过这些方法能够设置build方法获得的该phone实例的属性值要保证这些方法操作的是同一个phone实例要在Builder中提供phone成员变量 基于以上我们定义的PhoneBuilder如下 public class PhoneBuilder {private Phone phone new Phone();public PhoneBuilder color(String color) {this.phone.setColor(color);return this;}public PhoneBuilder battery(String battery) {this.phone.setBattery(battery);return this;}public PhoneBuilder screen(String screen) {this.phone.setScreen(screen);return this;}public PhoneBuilder os(String os) {this.phone.setOs(os);return this;}public PhoneBuilder camera(String camera) {this.phone.setCamera(camera);return this;}public Phone build() {return this.phone;} }使用如下 public class UseBuilder {public static void main(String[] args) {PhoneBuilder builder new PhoneBuilder();Phone phone builder.battery(4000毫安大容量).camera(徕卡顶级镜头).color(尊贵黑).screen(2K高清分辨率).os(Android).build();System.out.println(phone phone);} }上述代码是建造者模式最经典的使用方式。 建造者模式的优点如下 可以构造出复杂的对象。这个模式适用于某个对象的构建过程复杂的情况。不同的构建器相同的装配也可以做出不同的对象实现了更好的复用。建造者模式可以将部件和其组装过程分开一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象而无须知道其内部的具体构造细节。 采用链式调用一步一步把一个完整的对象构建出来。使用该模式是一次性将一个完整的对象构建出来更加的紧凑同时也避免了对象在其他处调用了set方法导致属性赋值错误。 建造者设计模式和工厂设计模式都是为了创建具体的实例工厂模式更关注通过什么工厂生产什么实例建造者模式主要是通过组装零配件而产生一个新产品 3.2 结构型模式 3.2.1 代理Proxy 代理是一种结构型设计模式可以允许我们生成对象的替代品。代理控制着对于原对象的访问同时也允许在原对象的方法之前前后做一些处理便可以实现在原方法执行前后都会执行某段代码逻辑的功能。这个也是面向切面编程的指导思想。 代理模式在软件开发过程中的应用场景也非常常见。在客户端以及客户端访问的目标类对象中间额外再引入一个第三方代理类对象。如果直接访问目标类对象就是执行对应的方法如果客户端访问的是代理类对象那么不仅可以访问对应的方法还会再方法的执行前后执行对应的前置、后置通知。 3.2.1.1 静态代理 public interface UserService {void insert(); }public class UserServiceImpl implements UserService {Overridepublic void insert() {System.out.println(目标类执行了insert方法);} }public class UserServiceProxy implements UserService {UserService target;public UserServiceProxy(UserService target) {//注入委托类对象this.target target;}Overridepublic void insert() {System.out.println(代理之前打印一个日志);target.insert();System.out.println(代理之后打印一个日志);} }Testpublic void test1(){UserServiceProxy proxy new UserServiceProxy(new UserServiceImpl());proxy.insert();}代理模式最大的优点在于可以不更改目标类代码的前提下扩展目标类代码的功能。 静态代理最大的缺点在于代码较为冗余每代理一个类便要手动编写一个代理类代理对象和目标类对象均实现了接口如果接口发生了修改不仅目标类需要更改代理类也需要同步发生修改维护成本变高了很多。 因此我们希望可以在程序运行过程中动态地生成一个代理类对象这样处理任务更加的方便。这也便是我们接下来介绍的动态代理。 3.2.1.2 JDK动态代理 静态代理顾名思义便是在编译时就已经实际存在了该class文件而动态代理在编译时期实际上并不存在该class文件而是程序在运行阶段动态生成了字节码。JDK动态代理即JDK给我们提供的动态生成代理类的方式无需引入第三方jar包但是使用JDK动态代理有一个先决条件那就是目标类对象必须实现了某个接口如果目标类对象没有实现任何接口则JDK动态代理无法使用。 如果使用JDK提供的动态代理那么需要借助于如下几个类 java.lang.reflect.Proxy API参数返回值public static Object newProxyInstance(ClassLoader loader, Class?[] interfaces, InvocationHandler h)loader表示目标类使用的类加载器interfaces表示目标类所实现的接口类型h表示处理器用来规定代理的内部细节返回一个实现指定接口的代理类实例对象代理类对象和目标类对象实现相同的接口类型 java.lang.reflect.InvocationHandler API参数返回值public Object invoke(Object proxy, Method method, Object[] args)proxy表示JDK帮助开发者生成的代理类对象这个参数一般不用理会method表示的是目标类中的方法args表示执行目标类方法时传递的参数三个参数合在一起表示的含义表示代理类如何来代理、增强目标类里面的方法代理类执行完对应的方法时它的返回值 public class ProxyFactory {Object target;public ProxyFactory(Object target) {this.target target;}public Object newProxyInstance(){return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {//代理类如何代理Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(代理之前签订合约);Object invoke method.invoke(target, args);System.out.println(代理完毕转账确认);return invoke;}});} }Testpublic void test2(){UserService userService new UserServiceImpl();//对哪个目标类进行代理我们对UserServiceImpl进行代理//生成代理类对象UserService userServiceProxy Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {//代理类如何代理Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(代理之前签订合约);Object invoke method.invoke(userService, args);System.out.println(代理完毕转账确认);return invoke;}});;//代理类对象执行insert方法什么逻辑呢主要是invoke里面的代码逻辑userServiceProxy.insert();}利用线上监测工具以及反编译工具可以看到生成的代理类对象源码 public final class $Proxy0 extends Proxy implements UserService {private static Method m1;private static Method m3;private static Method m2;private static Method m0;public $Proxy0(InvocationHandler invocationHandler) {super(invocationHandler);}static {try {m1 Class.forName(java.lang.Object).getMethod(equals, Class.forName(java.lang.Object));m3 Class.forName(com.cskaoyan.pattern.proxy.UserService).getMethod(insert, new Class[0]);m2 Class.forName(java.lang.Object).getMethod(toString, new Class[0]);m0 Class.forName(java.lang.Object).getMethod(hashCode, new Class[0]);return;}catch (NoSuchMethodException noSuchMethodException) {throw new NoSuchMethodError(noSuchMethodException.getMessage());}catch (ClassNotFoundException classNotFoundException) {throw new NoClassDefFoundError(classNotFoundException.getMessage());}}public final boolean equals(Object object) {try {return (Boolean)this.h.invoke(this, m1, new Object[]{object});}catch (Error | RuntimeException throwable) {throw throwable;}catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}}public final String toString() {try {return (String)this.h.invoke(this, m2, null);}catch (Error | RuntimeException throwable) {throw throwable;}catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}}public final int hashCode() {try {return (Integer)this.h.invoke(this, m0, null);}catch (Error | RuntimeException throwable) {throw throwable;}catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}}//主要关注insert方法public final void insert() {try {this.h.invoke(this, m3, null);return;}catch (Error | RuntimeException throwable) {throw throwable;}catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}} }3.2.1.3 Cglib动态代理 Cglib(Code Generation Library)是一个开源项目是一个强大的高性能高质量的Code生成类库它可以在运行期扩展Java类与实现Java接口。我们可以借助于Cglib来帮助我们动态地生成代理类对象。Cglib可以弥补JDK动态代理的不足JDK要求目标类必须实现了某个接口才可以执行代理功能而Cglib对此无任何要求主要原因在于Cglib扩展的代理类会继承自目标类。所以这也要求我们的目标类不能是final修饰。 使用Cglib涉及到的相关类如下 net.sf.cglib.proxy.Enhancer API参数返回值/说明enhancer.setSuperclass(superClass)父类的字节码对象也就是我们的目标类无返回值;Cglib产生的代理类会继承目标类所以此处设置的父类也就是目标类enhancer.setCallBack(callback)设置一个回调函数代理类对象如何代理目标对象需要在回调函数中制定策略CallBack是一个接口MethodInterceptor是一个子接口。我们选用该类来设置回调策略enhancer.create()-生成代理类对象 net.sf.cglib.proxy.MethodInterceptor API参数返回值/说明public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)第一个参数obj为代理类对象第二个参数为目标类对应中对应的方法第三个参数为目标类对象中对应的方法执行时传递的参数第四个参数是代理类对象中的对应方法返回值一般便将代理类对象对应方法的执行结果返回 使用Cglib需要导包 dependencygroupIdcglib/groupIdartifactIdcglib/artifactIdversion3.3.0/version /dependency创建一个目标类在这里为了体现Cglib的效果目标类没有实现任何接口 public class UserServiceImpl {public String getName(){System.out.println(目标方法执行);return zhangsan;} }编写测试代码 public class ProxyTest {public static void main(String[] args) {UserServiceImpl userService new UserServiceImpl();UserServiceImpl userServiceProxy Enhancer.create(UserServiceImpl.class,new InvocationHandler() {//代理类如何代理Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(目标方法执行之前);Object invoke method.invoke(userService, args);System.out.println(目标方法执行之后);return invoke;}});String name userServiceProxy.getName();System.out.println(name);} }3.3 行为型模式 3.3.1 责任链Responsibility Chain 责任链是一种行为设计模式允许请求沿着链进行发送。收到请求后每个处理者均可对请求进行处理或者将其传递给链上的下一个处理者。 对应的类关系如下 我们先举一个简单的例子提供三个处理器并处理好其先后关系然后分别依次处理那么我们要做的事情拆解如下 定义三个不同的处理器这三个处理器做的是类似的事情那么可以抽象一个接口或抽象类接下来就是关于抽象类中的方法要处理先后关系可以提供一个方法来处理处理器的顺序关系要做处理器的核心方法完成业务的处理每个处理器的处理方法的业务不同 将一些共性的部分放置在一个基类中其中提供的成员变量next能够维护顺序关系通过调用其提供的setNext方法完成顺序关系的维护handle方法能够提供不同的 public abstract class AbstractHandler {AbstractHandler next;public void setNext(AbstractHandler next){System.out.println(已经设置 this.getClass().getSimpleName() 的下一级为 next.getClass().getSimpleName());this.next next;}public abstract void handle(); }三个处理器 public class Level1Handler extends AbstractHandler{Overridepublic void handle() {System.out.println(一级处理器正在处理);if (next ! null) {next.handle();}} }public class Level2Handler extends AbstractHandler{Overridepublic void handle() {System.out.println(二级处理器正在处理);if (next ! null) {next.handle();}} }public class Level3Handler extends AbstractHandler{Overridepublic void handle() {System.out.println(三级处理器正在处理);if (next ! null) {next.handle();}} }最终的测试 public class ChainExecution {public static void main(String[] args) {Level1Handler level1Handler new Level1Handler();Level2Handler level2Handler new Level2Handler();Level3Handler level3Handler new Level3Handler();level2Handler.setNext(level3Handler);level1Handler.setNext(level2Handler);level1Handler.handle();} }next next; } public abstract void handle(); } 三个处理器java public class Level1Handler extends AbstractHandler{Overridepublic void handle() {System.out.println(一级处理器正在处理);if (next ! null) {next.handle();}} }public class Level2Handler extends AbstractHandler{Overridepublic void handle() {System.out.println(二级处理器正在处理);if (next ! null) {next.handle();}} }public class Level3Handler extends AbstractHandler{Overridepublic void handle() {System.out.println(三级处理器正在处理);if (next ! null) {next.handle();}} }最终的测试 public class ChainExecution {public static void main(String[] args) {Level1Handler level1Handler new Level1Handler();Level2Handler level2Handler new Level2Handler();Level3Handler level3Handler new Level3Handler();level2Handler.setNext(level3Handler);level1Handler.setNext(level2Handler);level1Handler.handle();} }责任链模式降低了系统之间的耦合性提升了系统的可扩展性。在很多中间件、框架的内部大量地使用了该种设计模式比如Filter的执行过程等。 4 附录 思维导图
http://www.dnsts.com.cn/news/195904.html

相关文章:

  • 宁波做亚马逊网站承德网站建设报价
  • 淘宝cms建站wordpress a
  • 营销企业网站建设应遵守的原则中国建设安全监理协会网站
  • 申办网站流程网站写好了怎么做后台管理
  • 北京住房与城乡建设厅网站自己电脑做电影网站吗
  • 企业做网站怎么做个人简历自我评价怎么写
  • 网站的电子画册怎么做枣庄做网站公司
  • 公司门户网站及oa系统建设的请示app推荐网站
  • 我有域名和服务器找人建设网站用代码做家乡网站
  • 全球排行前50网站开发语言做网站会提供源代码
  • 树状结构的网站使用wordpress做图站
  • 做网店好还是网站怎么做卖橘子的网站
  • 恶意刷网站嗨学网官网
  • 建网站空间都有什么平台wordpress主题等
  • 哪几个网站做acm题目温州网站优化指导
  • hao123网站模板深圳买房最新政策
  • 专门做电子书的网站有哪些最新消息新闻
  • 科技公司网站设建设电影网站广告哪里找
  • asp网站咋做国外代理网站
  • 一些可以做翻译的网站专做蓝领招聘网站有哪些
  • 大连企业网站模板建站中国域名注册局官网
  • 做设计不进设计公司网站安徽省住房城乡建设厅网站官网
  • 网站游戏下载九宫格导航网站
  • 网站建设有几个文件夹公司网站二维码生成器
  • 外贸英文网站开发网站主页面设计模板
  • 宁波网站建设制作公司排名定制虚拟偶像汉化破解版
  • 电子政务门户网站建设项目招标采购深圳网站开发antnw
  • 国外黄冈网站推广软件有哪些网站可以用中国二字做抬头吗
  • 低价网站建设顺德百度关键词规划师入口
  • 东莞贸易网站建设复杂的手游app要多少钱