设计模式三(行为模式一)

引用:runoob.com 设计模式

一,责任链模式(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个字母按照横竖划分, 将密文转为单词,如图


image.png

解释接口

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();
        }
    }

}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容