本文共 6913 字,大约阅读时间需要 23 分钟。
所有通过动态代理实现的方法全部通过invoke()
调用
使用静态代理时:
使用动态代理时:
要实现动态代理必须要有接口的,动态代理是基于接口来代理的(实现接口的所有方法),如果没有接口的话我们可以考虑cglib代理。
cglib代理也叫子类代理,从内存中构建出一个子类来扩展目标对象的功能!
一般来说,实现对象增强有三种方式:
继 承
装饰器模式
代理模式
继承
最简单的方式就是继承父类,子类扩展来达到目的。虽然简单,但是这种方式的缺陷非常大:
装饰器模式
单例模式定义很简单:一个类中能创建一个实例,所以称之为单例!
学过Java Web的同学可能就知道:
编写单例模式的代码其实很简单,就分了三步:
饿汉式
public class Java3y { // 1.将构造函数私有化,不可以通过new的方式来创建对象 private Java3y(){} // 2.在类的内部创建自行实例 private static Java3y java3y = new Java3y(); // 3.提供获取唯一实例的方法 public static Student getJava3y() { return java3y; }}
简单懒汉式
既然说一上来就创建对象,如果没有用过会造成内存浪费:
public class Java3y { // 1.将构造函数私有化,不可以通过new的方式来创建对象 private Java3y(){} // 2.1先不创建对象,等用到的时候再创建 private static Java3y java3y = null; // 2.1调用到这个方法了,证明是要被用到的了 public static Java3y getJava3y() { // 3. 如果这个对象引用为null,我们就创建并返回出去 if (java3y == null) { java3y = new Java3y(); } return java3y; }}
双重检测机制(DCL)懒汉式
public class Java3y { private Java3y() { } private static volatile Java3y java3y = null; public static Java3y getJava3y() { if (java3y == null) { // 将锁的范围缩小,提高性能 synchronized (Java3y.class) { // 再判断一次是否为null if (java3y == null) { java3y = new Java3y(); } } } return java3y; }}
静态内部类懒汉式
getInstance()
时,都会使SingletonHolder被加载和被初始化,此时静态初始化器将执行Singleton的初始化操作。(被调用时才进行初始化!)public class Java3y { private Java3y() { } // 使用内部类的方式来实现懒加载 private static class LazyHolder { // 创建单例对象 private static final Java3y INSTANCE = new Java3y(); } // 获取对象 public static final Java3y getInstance() { return LazyHolder.INSTANCE; }}
总的来说单例模式写法有5种:
厂模式分成三种:
定义一组算法,将每个算法都封装起来,并且使他们之间可以互换
优点:
算法可以自由切换
扩展性良好
缺点:
策略类的数量增多
所有的策略类都需要对外暴露
应用
学习ThreadPoolExecutor(线程池)就肯定要知道它的构造方法每个参数的意义:
RejectedExecutionHandler handler
其中我们可以找到RejectedExecutionHandler,这个参数代表的是拒绝策略(有四种具体的实现:直接抛出异常、使用调用者的线程来处理、直接丢掉这个任务、丢掉最老的任务)
【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
无论是空调、冰箱、电视、电脑、风扇等等,只要是电器都受这个电闸控制。只要这个电闸将关闭,所有的电器都会受到牵连(一同关闭)。
电源总开关(电闸)即为该系统的外观模式设计。
要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。
按照我们的例子,子系统就相当于电脑、冰箱、电视。统一的对象就相当于我们的电闸。我们通过电闸来对所有电器进行关闭(使得不用逐个逐个找电脑、冰箱、电视来关闭)
使用了门面模式,使客户端调用变得更加简单!
要点:
// 抽象模板类public abstract class WriteArticle { // 基本方法 protected abstract void introduction(); // 基本方法 protected abstract void theLast(); // 基本方法 protected abstract void actualContent(); // 模板方法 public final void writeAnCompleteArticle() { introduction(); actualContent(); theLast(); }}// 具体模板类public class Java3yWriteArticle extends WriteArticle { // 实现基本方法 @Override public void introduction() { System.out.println("只有充钱才能变强"); } // 实现基本方法 @Override public void theLast() { System.out.println("关注我的公众号:Java3y"); } // 实现基本方法 @Override protected void actualContent() { System.out.println("大家好,我是3y,今天来给大家分享我写的模板方法模式"); }}
基本方法:在子类实现,并且在模板方法中被调用
模板方法:定义了一个框架,实现对基本方法的调用,完成固定的逻辑。
定义一个操作中的算法框架,而将一些步骤延迟到子类中。
使子类可以不改变一个算法的结构即可重定义该算法的某些步骤
public class FilterChain { Listfilters = new ArrayList<>(); public FilterChain() { filters.add(new FilterEgg()); filters.add(new FilterAoBing()); filters.add(new FilterBaiCai()); filters.add(new FilterJiTou()); } public void processData(String data) { for (Filter filter : filters) { filter.doFilter(data); } }}
public class Handler { public void handlerRequest(Request request) { // 得到请求的数据 String data = request.getData(); FilterChain filterChain = new FilterChain(); // 处理数据 filterChain.processData(data); }}
if
和方法
)Chain
链起来,暴露一个方法给Handler使用那怎么实现建造者模式呢?其实也非常简单:
private
的构造函数,参数为Builder类型,里边将Builder的属性赋值给domain的属性build
方法,返回domain实例public class MessageTask { private String taskId; private String content; private String messageId; private String taskName; private MessageTask(Builder builder) { this.taskId = builder.taskId; this.content = builder.content; this.messageId = builder.messageId; this.taskName = builder.taskName; } public static class Builder{ private String taskId; private String content; private String messageId; private String taskName; public Builder setTaskId(String taskId) { this.taskId = taskId; return this; } public Builder setContent(String content) { this.content = content; return this; } public Builder setMessageId(String messageId) { this.messageId = messageId; return this; } public Builder setTaskName(String taskName) { this.taskName = taskName; return this; } // 创建build方法,返回实例 public MessageTask build() { return new MessageTask(this); } }}
使用方式:先创建Builder对象,然后用Builder去赋值,最后再调用build()
返回真正的实例:
MessageTask.Builder builder = new MessageTask.Builder();MessageTask task = builder.setContent("关注 Java3y 吧 >>") .setTaskId("3y") .setTaskName("一起来玩") .setMessageId(String.valueOf(ThreadLocalRandom.current().nextLong())) .build();
我们如果使用了Lombok
后,在类上加上一个注解@Builder
就可以使用建造者模式的代码了
@Builder@Datapublic class MessageTask { private String taskId; private String content; private String messageId; private String taskName;}
转载地址:http://qiwaz.baihongyu.com/