职责链模式(上)
职责链模式的原理和实现定义:将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这 些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。
在职责链模式中,多个处理器依次处理同一个请 求。一个请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再传递给 C 处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作职责链模式。
一个具体的demo如下:
如果它能处理该请求,就不继续往下传递;如果不能处理,则交由后面的处理器来处理(也 就是调用 successor.handle())
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061public abstract class Handler { protected Handler successor = null; public void setSuc ...
策略模式
策略模式,最常见的应用场景是,利用它来避免冗长的 if-else 或 switch 分支判断,它也可以像模板模式那样,提供框架的扩展点等等。
策略模式的原理与实现定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。策略 模式可以使算法的变化独立于使用它们的客户端(这里的客户端代指使用算法的代码)。
工厂模式是解耦对象的创建和使用,观察者模式是解耦观察者和被观察者,策略模式跟两者类似,也能起到解耦的作用,不过,它解耦的是策略的定义、创建、使用这三部分。
1. 策略的定义策略类的定义比较简单,包含一个策略接口和一组实现这个接口的策略类。
123456789101112131415public interface Strategy { void algorithmInterface();}public class ConcreteStrategyA implements Strategy { @Override public void algorithmInterface() { //具体的算法... ...
模板方法(下)
回调也可以实现类似于模板模式的作用。
回调的原理解析相对于普通的函数调用来说,回调是一种双向调用关系。A 类事先注册某个函数 F 到 B 类,A 类在调用 B 类的 P 函数的时候,B 类反过来调用 A 类注册给它的 F 函数。这里的 F 函数就是“回调函数”。A 调用 B,B 反过来又调用 A,这种调用机制就叫作“回调”。
A 类如何将回调函数传递给 B 类呢?不同的编程语言,有不同的实现方法。C 语言可以使 用函数指针,Java 则需要使用包裹了回调函数的类对象,我们简称为回调对象。
12345678910111213141516171819202122public interface ICallback { void methodToCallback();}public class BClass { public void process(ICallback callback) { //... callback.methodToCallback(); //... } ...
模板方法(上)
模板模式的原理与实现模板方法模式在一个方法中定义一个算法骨架,并将某些步骤推迟到子类 中实现。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些 步骤。
一个具体的例子如下:
123456789101112131415161718192021222324252627282930313233public abstract class AbstractClass { public final void templateMethod() { //... method1(); //... method2(); //... } protected abstract void method1(); protected abstract void method2();}public class ConcreteClass1 extends AbstractClass { @Override protected void me ...
观察者模式(下)
观察者模式有几种不同的实现方式:同步阻塞、异步非阻塞、进程内、进程间的实现方式。
同步阻塞是最经典的实现方式,主要是为了代码解耦;异步非阻塞除了能实现代码解耦之 外,还能提高代码的执行效率;进程间的观察者模式解耦更加彻底,一般是基于消息队列来 实现,用来实现不同进程间的被观察者和观察者之间的交互。
异步非阻塞观察者模式的简易实现有两种实现方式:其中一种是:在每个 handleRegSuccess() 函数中创建一个新的线 程执行代码逻辑;另一种是:在 UserController 的 register() 函数中使用线程池来执行每 个观察者的 handleRegSuccess() 函数。
1234567891011121314151617181920212223242526272829303132333435363738394041// 第一种实现方式,其他类代码不变,就没有再重复罗列public class RegPromotionObserver implements RegObserver { private PromotionService promotionS ...
观察者模式(上)
观察者模式(Observer Design Pattern)也被称为发布订阅模式,在《设计模式》一书中,它的定义如下:
在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。
一个具体的代码示例如下:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647public interface Subject { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(Message message);}public interface Observer { void update(Message message);}public class ConcreteSubject implements Subject { ...
享元模式(下)
享元模式在 Java Integer 中的应用自动装箱与自动拆箱Java中的基本数据类型对应的有包装器类型,他们之前存在着自动装箱和拆箱的过程。
所谓的自动装箱,就是自动将基本数据类型转换为包装器类型。所谓的自动拆箱,也就是自 动将包装器类型转化为基本数据类型。具体的代码示例如下所示:
12Integer i = 56; //自动装箱int j = i; //自动拆箱
数值 56 是基本数据类型 int,当赋值给包装器类型(Integer)变量的时候,触发自动装箱 操作,创建一个 Integer 类型的对象,并且赋值给变量 i。其底层相当于执行了下面这条语句:
1Integer i = 59;底层执行了:Integer i = Integer.valueOf(59);
反过来,当把包装器类型的变量 i,赋值给基本数据类型变量 j 的时候,触发自动拆箱操 作,将 i 中的数据取出,赋值给 j。其底层相当于执行了下面这条语句:
1int j = i; 底层执行了:int j = i.intValue();
对象存储1User a = new User(123, 23); // id= ...
享元模式(上)
享元模式的意图是复用对象,节省内存,前提是享元对象是不可变对象。
具体来讲,当一个系统中存在大量重复对象的时候,如果这些重复的对象是不可变对象,我 们就可以利用享元模式将对象设计成享元,在内存中只保留一份实例,供多处代码引用。这 样可以减少内存中对象的数量,起到节省内存的目的。
享元模式的两个应用场景1、在象棋游戏中,每一句的棋子都是一样的,当有多个玩家时,不同玩家之间只是象棋的位置不同,那么我们就可以将一些基础的属性抽出来,供多个人使用,节省了内存。
2、文本编辑器中,每一个字体都可以单独的设置格式。对于字体格式,我们可以将它设计成享元,让不同的文字共享使用。
享元模式 vs 单例、缓存、对象池享元模式跟单例的区别在单例模式中,一个类只能创建一个对象,而在享元模式中,一个类可以创建多个对象,每 个对象被多处代码引用共享。实际上,享元模式有点类似于之前讲到的单例的变体:多例
应用享元模式是为了对象复用,节省内存,而应用单例模式是为 了限制对象的个数。
享元模式跟缓存的区别在享元模式的实现中,我们通过工厂类来“缓存”已经创建好的对象。这里的“缓存”实际 上是“存储”的意思,跟我们平时所说 ...
适配器模式
适配器模式,这个模式就是用来做适配的,它将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类可以一起工作。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859// 类适配器: 基于继承public interface ITarget { void f1(); void f2(); void fc();}public class Adaptee { public void fa() { //... } public void fb() { //... } public void fc() { //... }}public class Adaptor extends Adaptee implement ...
装饰器模式
装饰器模式理论装饰器模式相对于简单的组合关系,还有两个比较特殊的地方。
1、装饰器类和原始类继承同样的父类,这样我们可以对原始类“嵌套”多个装饰器类。
比如下面这种,他就是对DataInputStream的一种增强,装进了一个FileInputStream和BufferedInputStream
1234InputStream in = new FileInputStream("/user/wangzheng/test.txt");InputStream bin = new BufferedInputStream(in);DataInputStream din = new DataInputStream(bin);int data = din.readInt();
2、装饰器类是对功能的增强,这也是装饰器模式应用场景的一个重 要特点。
12345678910111213141516171819202122232425262728293031323334353637383940414243// 代理模式的代码结构(下面的接口也可以替换成抽象类)public inte ...