Android开发Android技术知识Android开发

行为型设计模式总结

2021-04-27  本文已影响0人  奔跑吧李博

Observer模式作用是当一个对象发生变化时,能够自动通知它的观察者刷新状态。Observer模式提供给关联对象一种同步通信的手段,使某个对象与其它依赖它的对象保持状态同步。

模式结构图:
模式的角色和职责

Subject(被观察者):被观察的对象。当被观察的状态发生变化时,需要通知队列中所有观察者对象。subject需要维持一个观察者对象的队列列表。
ConcreteSubject:被观察者的具体实现。
Observer(观察者):接口或抽象类。当subject的状态发生变化时,Observer对象将通过一个Callback函数得到通知。
ConcreteObserver:观察者的具体实现。

示例:

作者发布一篇简书文章,让所有订阅者都收到该文章。

文章Article类:

class Article {

    private String title;
    private String content;
    private String author;

    public String getTitle() {
        return title == null ? "" : title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content == null ? "" : content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getAuthor() {
        return author == null ? "" : author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}

具体的被观察者ArticelOperation类:

/**
 * 被观察者需要继承Observable接口
 */
class ArticelOperation extends Observable {

    /**
     * 发布一篇文章
     */
    public void publish(String title, String content, String author) {
        Article article = new Article();
        article.setTitle(title);
        article.setContent(content);
        article.setAuthor(author);
        this.setChanged();  //通知状态改变

        this.notifyObservers(article); //通知所有观察者对象状态改变了
    }
}

两个观察者类Observer和Observer2:

class Observer implements java.util.Observer {

    @Override
    public void update(Observable o, Object arg) {
        Article article = (Article) arg;

        System.out.println(getClass().getSimpleName() + "  " + article.getTitle());
        System.out.println(getClass().getSimpleName() + "  " + article.getContent());
        System.out.println(getClass().getSimpleName() + "  " + article.getAuthor());

    }
}

class Observer2 implements java.util.Observer {

    @Override
    public void update(Observable o, Object arg) {
        Article article = (Article) arg;

        System.out.println(getClass().getSimpleName() + "  " + article.getTitle());
        System.out.println(getClass().getSimpleName() + "  " + article.getContent());
        System.out.println(getClass().getSimpleName() + "  " + article.getAuthor());

    }
}

执行测试:

    public static void main(String[] args) {

        //创建一个观察者文章作者
        ArticelOperation article = new ArticelOperation();
        //添加各个观察者进行监听
        article.addObserver(new Observer());
        article.addObserver(new Observer2());

        //作者发布文章
        //article调用publish会调用自身notifyObservers,通知各个observer对象调用自己的update方法,收到该事件的回调。
        article.publish("Android进阶解密", "解读Android源码", "刘皇叔");
    }

执行结果,两个观察者都收到了作者的发布内容。


定义一个操作的算法的骨架,而将一些算法操作步骤延迟到子类中。模板方法使得子类可以不改变算法的结构可重定义的某些特定步骤。

Template Method模式一般应用在具有以下条件的应用中:
1.具有统一的操作步骤或操作过程。
2.具有不同的操作细节。
3.存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同。

模式结构图:
示例:

定义做饭的抽象,将具体做的细节延迟到子类去实现,并定义make方法,将操作步骤统一起来,方便按自己的顺序一次性调用。

public abstract class MakeFood {

    //准备食材
    abstract void prepare();

    //进行做饭
    abstract void doing();

    //装盘
    abstract void carryOut();

    //再将操作步骤统一起来
    public void make() {
        prepare();
        doing();
        carryOut();
    }
}

实现MakeFood接口,做两个菜,将具体做法自己实现。

/**
 * 做一个西红柿鸡蛋
 */
class MakeTomatoEgg extends MakeFood {

    @Override
    void prepare() {
        System.out.println("准备西红柿鸡蛋");
    }

    @Override
    void doing() {
        System.out.println("抄西红柿鸡蛋");
    }

    @Override
    void carryOut() {
        System.out.println("装盘");
    }
}

/**
 * 炒肉
 */
class MakeMeet extends MakeFood {

    @Override
    void prepare() {
        System.out.println("准备肉");
    }

    @Override
    void doing() {
        System.out.println("炒肉");
    }

    @Override
    void carryOut() {
        System.out.println("装盘");
    }
}

测试执行:

    public static void main(String[] args) {
        MakeFood makeFood = new MakeTomatoEgg();
//        MakeFood makeFood = new MakeMeet();
        makeFood.make();
    }

结果:


模板方法模式优缺点:

优点:封装不变部分,扩展可变部分;提取公共代码,便于维护;行为由父类控制,具体由子类实现。
缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,是的系统更加庞大。

策略模式指的是对象具备某个行为,但是在不同的场景中,该行为有不同的实现算法。

模式结构:

模式的角色和职责:
Strategy:策略(算法)抽象
ConcreteStrategy:各种策略(算法)的具体实现。
Context:策略的外部封装类,或者说策略的容器类。根据不同策略执行不同的行为。

示例:

加密模式有MD5加密和Des加密,使用不同策略就分别使用各自的加密方式。

策略接口

interface Strategy {

    public void encrypt();
}

Md5Strategy加密策略:

class Md5Strategy implements Strategy {

    @Override
    public void encrypt() {
        System.out.println("MD5加密");
    }
}

DesStrategy加密策略:

class DesStrategy implements Strategy {

    @Override
    public void encrypt() {
        System.out.println("DES加密");
    }
}

策略的容器类Context:

class Context {

    public Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void encrypt() {
        strategy.encrypt();
    }
}

执行测试:

    public static void main(String[] args) {

        Context context = new Context(new Md5Strategy());
//        Context context = new Context(new DesStrategy());
        context.encrypt();
    }

根据采用的不同Strategy实例,使用对应的算法策略。

策略模式优缺点:

优点:策略模式提供了管理相关的算法族的办法。
缺点:客户端必须知道所有的策略,并自行决定使用哪一个策略类。

责任链(Chain of Responsibility)模式的定义:为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

优点:解耦,简化操作。
缺点:性能会有一点影响,调试不太方便。

示例:

仿照okhttp库做各种拦截器:

责任链接口

interface Interceptor {
    String chain(String data);
}

创建缓存拦截器:

class CacheInterceptor implements Interceptor {

    @Override
    public String chain(String data) {
        return data = data + "缓存拦截器处理 ->";
    }
}

创建请求拦截器:

class CallServerInterceptor implements Interceptor {

    @Override
    public String chain(String data) {
        return data = data + "请求拦截器处理 ->";
    }
}

把责任链集合起来,遍历调用各个责任链的处理方法,并将结果传递给下一个责任链:

class RealInterceptor {
    List<Interceptor> list = new ArrayList<>();

    public RealInterceptor() {
        list.add(new CacheInterceptor());
        list.add(new CallServerInterceptor());
    }

    public String request(String data) {
        for (Interceptor interceptor: list) {
            data = interceptor.chain(data);
        }
        return data;
    }
}

执行并打印结果:

    public static void main(String[] args) {
        String request = new RealInterceptor().request("request->");
        System.out.println(request);
    }
上一篇 下一篇

猜你喜欢

热点阅读