设计模式3(行为模式)

设计模式3(行为模式)

行为模式
这类模式负责对象间的高效沟通和职责委派

unknown_filename.4

命令模式

用得少

迭代器模式

特点是实现 Iterable 接口,通过 next 的方式获取集合元素,同时具备对元素的删除等操作

中介者模式

中介者模式要解决的就是复杂功能应用之间的重复调用,在这中间添加一层中介者包装服务,对外提供简单、通用、易扩展的服务能力。
这种模式的设计满足了; 单一职责 和 开闭原则,也就符合了迪米特原则,即越少人知道越好。外部的人只需要按照需求进行调用,不需要知道具体的是如何实现的
unknown_filename.5|474x0

模板方法模式

(AsnycTask、Activity)
提供一个抽象类,将部分逻辑以具体方法或构造器的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法(多态实现),从而实现不同的业务逻辑。
unknown_filename|669x0

temple和concrete继承关系,三角箭头实线

使用场景

1)多个子类有公有的方法,并且逻辑基本相同时
2)重要、复杂的算法,可以把核心算法设计为模板方法
3)重构时,模板方法模式是一个经常使用的模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public abstract class AbstractWork {

    protected void getUp() {
        System.out.println("起床啦!");
    }
    protected abstract void goToWork();
    protected abstract void work();
    protected abstract void getOffWork();
    /*
     * TemplateMethod,大家都拥有共同的执行步骤
     */
    public final void newDay() {
        getUp();
        goToWork();
        work();
        getOffWork();
    }
}

public class StaffWork extends AbstractWork {

    @Override
    protected void goToWork() {
        System.out.println("员工做公交去上班");
    }
    @Override
    protected void work() {
        System.out.println("员工处理具体工作");
    }
    @Override
    protected void getOffWork() {
        System.out.println("员工做公交下班");
    }
}

策略

(Volley)替换if else
定义了一些算法,分别封装起来。让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的调用者。
一个类定义了多种行为,并且这些行为在这个类的方法中以多个条件语句的形式出现,那么可以使用策略模式避免在类中使用大量的条件语句。

unknown_filename.1|630x0

strategy和concrete是继承关系,三角箭头实线
context和strategy是聚合关系,空心菱形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public interface AbstractStrategy {
    //按距离来计算价格
    int calculatePrice(int km);
}

public class BusStrategy implements AbstractStrategy {
    @Override
    public int calculatePrice(int km) {
        return km;
    }
}

public class TaxiStrategy implements AbstractStrategy {
    @Override
    public int calculatePrice(int km) {
        return km * 2;
    }
}

public class Context {
    private AbstractStrategy strategy;
    public void setStrategy(AbstractStrategy strategy) {
        this.strategy = strategy;
    }

    public int calclatePrice(int km) {
        return strategy.calculatePrice(km);
    }

    public static void main(String[] strings) {
        Context calculator = new Context();
        calculator.setStrategy(new BusStrategy());
//        calculator.setStrategy(new TaxiStrategy());
        System.out.println("公交车20km价格:" + calculator.calclatePrice(20));
    }

}

传统写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    //PriceCalculator 类很明显的问题就是并不是单一职责,首先它承担计算公交车和地铁乘坐价格的职责,
    //另一个问题就是通过if-else的形式来判断使用哪种计算形式。当我们增加一种出行方式时,如出租车,
    //那么我们就需要在PriceCalculator 中增加一个方法来计算出租车出行的价格,并且在calculatePrice(int km, int type)函数增加一个判断
    public static class PriceCalculator {
        private static final int TAXI = 3;
        private static final int BUS = 1;
        private static final int SUBWAY = 2;

        public static void main(String[] strings) {
            PriceCalculator calculator = new PriceCalculator();
            System.out.println("做20km公交票价:" + calculator.calculatePrice(20, BUS));
            System.out.println("做20km地铁票价:" + calculator.calculatePrice(20, SUBWAY));
        }

        private int busPrice(int km) {
            return km * 1;
        }
        public int taxiPrice(int km) {
            return km * 7;
        }

        /**
         * 根据不同类型计算
         */
        int calculatePrice(int km, int type) {
            if (type == BUS) {
                return busPrice(km);
            } else if (type == SUBWAY) {
                return taxiPrice(km);
            }
            return 0;
        }
    }

观察者模式

定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象都可得到通知并被自动更新。(android中的回调模式、listview的notifyDataChanged、rxjava)

观察者模式在android中的实际运用:回调模式

回调模式:实现了抽象类/接口的实例实现了父类的提供的抽象方法后,将该方法交还给父类来处理。
例如:通过 setOnClickListener() 方法,Button 持有 OnClickListener 的引用(这一过程没有在图上画出);当用户点击时,Button 自动调用 OnClickListener 的 onClick() 方法。另外,如果把这张图中的概念抽象出来

(Button(view) -> 被观察者、OnClickListener -> 观察者、setOnClickListener() -> 订阅,onClick() -> 事件),就由专用的观察者模式(例如只用于监听控件点击)转变成了通用的观察者模式。

unknown_filename.2|438x0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class ObserverPattern {

    public interface Observer {
        void update(String state);
    }

    public class ConcreteObserver implements Observer {
        // 观察者状态
        private String observerState;

        @Override
        public void update(String state) {
            // 更新观察者状态,让它与目标状态一致
            observerState = state;
            System.out.println("ConcreteObserver State :" + observerState);
        }
    }

    /**
     * 抽象订阅者(目标者)
* 被观察者
     *
     */
    public abstract class Subject {

        // 保存注册的观察者对象
        private List<Observer> mObservers = new ArrayList<>();

        //注册观察者对象
        public void attach(Observer observer) {
            mObservers.add(observer);
            System.out.println("Attached an observer");
        }

        //注销观察者对象
        public void detach(Observer observer) {
            mObservers.remove(observer);
        }

        // 通知所有注册的观察者对象
        public void nodifyObservers(String newState) {
            for (Observer observer : mObservers) {
                observer.update(newState);
            }
        }
    }

    public class ConcreteSubject extends Subject {

        private String state;

        public String getState() {
            return state;
        }

        public void change(String newState) {
            state = newState;
            System.out.println("ConcreteSubject State:" + state);
            //状态发生改变,通知观察者
            nodifyObservers(state);
        }
    }

    public static void main(String[] args) {
        ObserverPattern observerPattern = new ObserverPattern();
        ConcreteSubject concreteSubject = observerPattern.new ConcreteSubject();
        Observer observer1 = observerPattern.new ConcreteObserver();
        Observer observer2 = observerPattern.new ConcreteObserver();
        // 将观察者对象注册到目标对象上
        concreteSubject.attach(observer1);
        concreteSubject.attach(observer2);
        // 改变目标对象的状态
        concreteSubject.change("I change");
    }
}

安卓自己的观察者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MessageObserver implements Observer {

    @Override
    public void update(Observable observable, Object o) {
        Message  message=(Message)o;
    }
}

    class MessageObservable extends java.util.Observable {

        public void registerMessageObserver(Observer observer) {
            addObserver(observer);
        }

        public void unRegisterMessageObserver(Observer observer) {
            addObserver(observer);
        }

        private void onMessage(Message message) {
            setChanged();
            notifyObservers(message);
        }
    }

责任链模式

(try-catch、有序广播、viewgroup 事件传递)
一个请求有多个对象来处理,这些对象是一条链,但具体由哪个对象来处理,根据条件判断来确定,如果不能处理会传递给该链中的下一个对象,直到有对象处理它为止

使用场景

  • 多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定
  • 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求

unknown_filename.3|601x0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
public class Chain {

    public abstract class Handler {

        private Handler nextHandler;

        // 当前领导能审批通过的最多天数
        public int maxDay;

        protected Handler(int maxDay) {
            this.maxDay = maxDay;
        }

        //设置责任链中下一个处理请求的对象
        public void setNextHandler(Handler handler) {
            nextHandler = handler;
        }

        protected void handleRequest(int day) {
            if (day <= maxDay) {
                reply(day);
            } else {
                if (nextHandler != null) {
                    //审批权限不够,继续上报
                    nextHandler.handleRequest(day);
                } else {
                    System.out.println("没有更高的领导审批了");
                }
            }
        }

        protected abstract void reply(int day);
    }

    class ProjectManager extends Handler {
        public ProjectManager(int day) {
            super(day);
        }

        @Override
        protected void reply(int day) {
            System.out.println(day + "天请假,项目经理直接审批通过");
        }
    }

    class DepartmentManager extends Handler {
        public DepartmentManager(int day) {
            super(day);
        }

        @Override
        protected void reply(int day) {
            System.out.println(day + "天请假,部门经理审批通过");
        }
    }

    class GeneralManager extends Handler {
        public GeneralManager(int day) {
            super(day);
        }

        @Override
        protected void reply(int day) {
            System.out.println(day + "天请假,总经理直接审批通过");
        }
    }

    public static void main(String[] strings) {
        Chain chain = new Chain();
        Handler projectManager = chain.new ProjectManager(3);
        Handler departmentManager = chain.new DepartmentManager(5);
        Handler generalManager = chain.new GeneralManager(15);
        //创建职责链
        projectManager.setNextHandler(departmentManager);
        departmentManager.setNextHandler(generalManager);
        //发起请假请求
        projectManager.handleRequest(4);
    }
}

设计模式3(行为模式)
http://peiniwan.github.io/2024/04/9f305c079075.html
作者
六月的雨
发布于
2024年4月6日
许可协议