一,责任链模式(Chain of Responsibility Pattern)
为请求创建了一个接收者对象的链, 如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。
职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
案例: 餐厅内,加水,上米饭, 上菜分三个人进行
抽象服务类
public abstract class Waiter {
public static int NEED_WATER = 1;
public static int NEED_RICE = 2;
public static int NEED_DISHES = 3;
public static int NEED_OTHER = 4;
protected int serviceType;
protected Waiter nextWait;
public void setNextWait(Waiter nextWait) {
this.nextWait = nextWait;
}
public abstract void doService();
public void need(int type){
if (this.serviceType == type) {
doService();
} else if (null != nextWait) {
nextWait.need(type);
} else {
System.out.println("这里是饭店, 请不要提无理的要求~");
}
}
}
四个实现类
public class Manager extends Waiter {
public Manager(int serviceType) {
this.serviceType = serviceType;
}
@Override
public void doService() {
System.out.println("你要的东西么得");
}
}
public class Water extends Waiter {
public Water(int serviceType) {
this.serviceType = serviceType;
}
@Override
public void doService() {
System.out.println("你要的水来了!!!");
}
}
public class Rice extends Waiter {
public Rice(int serviceType) {
this.serviceType = serviceType;
}
@Override
public void doService() {
System.out.println("你要的米饭来了!!!");
}
}
public class Dishes extends Waiter {
public Dishes(int serviceType) {
this.serviceType = serviceType;
}
@Override
public void doService() {
System.out.println("你要的菜来了!!!!");
}
}
Demo
public static void main(String[] args) {
Manager manager = new Manager(Waiter.NEED_OTHER);
Water water = new Water(Waiter.NEED_WATER);
Rice rice = new Rice(Waiter.NEED_RICE);
Dishes dishes = new Dishes(Waiter.NEED_DISHES);
water.setNextWait(rice);
rice.setNextWait(dishes);
dishes.setNextWait(manager);
// 你要的米饭来了!!!
water.need(Waiter.NEED_RICE);
// 你要的东西么得
water.need(Waiter.NEED_OTHER);
// 这里是饭店, 请不要提无理的要求~
water.need(5);
}
二,命令模式(Command Pattern)
请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
案例:
请求类, 分为三个命令
public class Service {
public void getWater(){
System.out.println("一壶水");
}
public void getRice(){
System.out.println("一碗米饭");
}
public void getDishes(){
System.out.println("一碗菜");
}
}
可以执行命令的类, 它们实现执行接口
public interface Waiter {
void doService();
}
public class Water implements Waiter {
private Service service;
public Water(Service service) {
this.service = service;
}
@Override
public void doService() {
service.getWater();
}
}
public class Rice implements Waiter {
private Service service;
public Rice(Service service) {
this.service = service;
}
@Override
public void doService() {
service.getRice();
}
}
public class Dishes implements Waiter {
private Service service;
public Dishes(Service service) {
this.service = service;
}
@Override
public void doService() {
service.getDishes();
}
}
调用对象, 作为中间人, 负责连接 请求和执行对象
public class Broker {
private List<Waiter> needList = new ArrayList<>();
public void addNeed(Waiter waiter) {
needList.add(waiter);
}
public void doService(){
for (Waiter waiter : needList) {
waiter.doService();
}
}
}
Demo
public static void main(String[] args) {
Service service = new Service();
Rice rice = new Rice(service);
Water water = new Water(service);
Dishes dishes = new Dishes(service);
Broker broker = new Broker();
broker.addNeed(water);
broker.addNeed(rice);
broker.addNeed(dishes);
broker.doService();
}
一壶水
一碗米饭
一碗菜
责任链模式主要是将各个责任方(实现不同功能的对象), 以链表的形式连接, 每个节点如果接收到不是自己执行的命令(一般以简单的数值区分), 就往下传递.
命令模式是将命令封装为对象, 建立中间者, 负责将命令的发送方和执行方连接, 寻找命令的执行方, 进行命令的执行.
三,解释器模式(Interpreter Pattern)
提供了评估语言的语法或表达式的方式,这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。
案例: 简单的将26个字母按照横竖划分, 将密文转为单词,如图
解释接口
public interface Expression {
// 解释字符
List<Character> interpret(Character c);
}
2个解释类
public class NumberExp implements Expression {
private HashMap<Character, List<Character>> map;
public NumberExp() {
init();
}
@Override
public List<Character> interpret(Character c) {
return map.get(c);
}
private void init(){
map = new HashMap<>();
ArrayList<Character> c1 = new ArrayList<>();
ArrayList<Character> c2 = new ArrayList<>();
ArrayList<Character> c3 = new ArrayList<>();
ArrayList<Character> c4 = new ArrayList<>();
ArrayList<Character> c5 = new ArrayList<>();
c1.add('a');c1.add('b');c1.add('c');c1.add('d');c1.add('e');c1.add('f');
c2.add('g');c2.add('h');c2.add('i');c2.add('j');c2.add('k');c2.add('l');
c3.add('m');c3.add('n');c3.add('o');c3.add('p');c3.add('q');c3.add('r');
c4.add('s');c4.add('t');c4.add('u');c4.add('v');c4.add('w');c4.add('x');
c5.add('y');c5.add('z');c5.add(' ');c5.add(',');c5.add('.');c5.add('!');
map.put('1', c1); map.put('2', c2); map.put('3', c3);
map.put('4', c4); map.put('5', c5);
}
}
public class LetterExp implements Expression {
private HashMap<Character, List<Character>> map;
public LetterExp() {
init();
}
@Override
public List<Character> interpret(Character c) {
return map.get(c);
}
private void init(){
map = new HashMap<>();
ArrayList<Character> ca = new ArrayList<>();
ArrayList<Character> cb = new ArrayList<>();
ArrayList<Character> cc = new ArrayList<>();
ArrayList<Character> cd = new ArrayList<>();
ArrayList<Character> ce = new ArrayList<>();
ArrayList<Character> cf = new ArrayList<>();
ca.add('a');cb.add('b');cc.add('c');cd.add('d');ce.add('e');cf.add('f');
ca.add('g');cb.add('h');cc.add('i');cd.add('j');ce.add('k');cf.add('l');
ca.add('m');cb.add('n');cc.add('o');cd.add('p');ce.add('q');cf.add('r');
ca.add('s');cb.add('t');cc.add('u');cd.add('v');ce.add('w');cf.add('x');
ca.add('y');cb.add('z');cc.add(' ');cd.add(',');ce.add('.');cf.add('!');
map.put('A', ca);map.put('B', cb);map.put('C', cc);
map.put('D', cd);map.put('E', ce);map.put('F', cf);
}
}
Demo
public static void main(String[] args) {
String pwd = "B2E1F2F2C3C5E4C3F3D1";
System.out.println(converPwd(pwd)); // hello word
}
public static String converPwd(String pwd) {
char[] chars = pwd.toCharArray();
LetterExp letterExp = new LetterExp();
NumberExp numberExp = new NumberExp();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < chars.length; i+=2) {
List<Character> cList1 = letterExp.interpret(chars[i]);
List<Character> cList2 = numberExp.interpret(chars[i + 1]);
for (Character character : cList1) {
if (cList2.contains(character)) {
builder.append(character);
continue;
}
}
}
return builder.toString();
}
四,迭代器模式(Iterator Pattern)
这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。
案例1:
迭代器接口, 提供判断和获取下一个元素的接口
public interface Iterator {
boolean hasNext();
Object next();
}
集合接口和集合类, 实现提供迭代器的接口
public interface Container {
Iterator getIterator();
}
public class Names implements Container {
private String[] names = {"张三", "李四", "王五"};
@Override
public Iterator getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator{
private int index;
@Override
public boolean hasNext() {
return index < names.length;
}
@Override
public Object next() {
if (hasNext()) {
return names[index++];
}
return null;
}
}
}
Demo
public static void main(String[] args) {
Names names = new Names();
Iterator iterator = names.getIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next().toString());
}
}
案例2: Java中的迭代器:
迭代器接口
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
// 对剩余的元素,分别进行消费
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
集合类实现的可迭代接口
public interface Iterable<T> {
Iterator<T> iterator();
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
集合接口
public interface Collection<E> extends Iterable<E> {
......
Iterator<E> iterator();
......
}
public interface List<E> extends Collection<E> {
......
Iterator<E> iterator();
......
}
ArrayList
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
... ...
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}