• 23种设计模式(一)-组件协作模式


    典型的三种组件协作模式

    Template Method:模板方法模式

    在软件构建过程中,对于某项任务,常常有稳定的整体操作结构,但是各个子步骤却有很多改变的需求,或者由于固有的原因无法和任务整体结构同时实现。

    定义一个算法的骨架,讲一些步骤(变化的)延迟到子类中,是的子类可以复用一个算法的结构(骨架)并重新定义(overwrite)某些特定的步骤

    eg1:不使用Template Method
    public class TemplateMethod {
        public boolean stap2() {
            return false;
        }
    
        public void stap4() {
        }
    
        public void run() {
            TemplateMethod templateMethod = new TemplateMethod();
            Lib lib = new Lib();
            try {
                lib.stap1();
                if (templateMethod.stap2()) {
                    lib.stap3();
                } else {
                    templateMethod.stap4();
                }
                lib.stap5();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    class Lib {
        public void stap1() {
        }
    
        public boolean stap3() {
            return false;
        }
    
        public void stap5() {
        }
    }
    

    弊端:TemplateMethod 要实现 run()、 stap2() 、stap4()方法,然而run()在此例中属于比较稳定的模块,属于整个算法的骨架。属于子类调用父类方法(早绑定)

    eg2:使用Template Method
    public class TemplateMethod2 extends Lib2 {
    
        @Override
        public boolean stap2() {//变化点
            return false;
        }
    
        @Override
        public void stap5() {//变化点
        }
    
        public static void main(String[] args) {
            Lib2 templateMethod2 = new TemplateMethod2();
            templateMethod2.run();
        }
    }
    
    abstract class Lib2 {
        public void stap1() {
        }
    
        public abstract boolean stap2();// 声明为抽象方法
    
        public boolean stap3() {
            return false;
        }
    
        public void stap4() {
        }
    
        public abstract void stap5(); // 声明为抽象方法
    
        public void run() {  //稳定骨架(模板)
            try {
                stap1();
                if (stap2()) {
                    stap3();
                } else {
                    stap4();
                }
                stap5();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    优点:TemplateMethod2 要实现 stap2() 、stap4()方法,然而run()在此例中属于比较稳定的模块,属于整个算法的骨架已经在父类中实现。属于父类调用子类方法(晚绑定)。

    模板方法模式类图.png

    Strategy:策略模式

    在软件构建过程中,某些对象使用个算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使得对象变得异常复杂;而且有时候支持不是用的算法也是一个性能负担。

    定义一系列算法,把它们一个个封装起来,并且使它们可以互相替换(变化)。该模式使得算法可以独立于使用它的客户程序(稳定)而变化(扩展、子类化).

    //策略接口
    public interface Strategy {
        //定义的抽象算法方法 来约束具体的算法实现方法
        public void algorithmMethod();
    }
    
    // 具体的策略实现1
    class ConcreteStrategy1 implements Strategy {
        //具体的算法实现
        @Override
        public void algorithmMethod() {
            System.out.println("ConcreteStrategy1");
        }
    }
    
    // 具体的策略实现2
    class ConcreteStrategy2 implements Strategy {
        //具体的算法实现
        @Override
        public void algorithmMethod() {
            System.out.println("ConcreteStrategy2");
        }
    }
    
    //策略上下文
    class StrategyContext {
        private Strategy strategy;//持有一个策略实现的引用
    
        public StrategyContext(Strategy strategy) { //使用构造器注入具体的策略类
            this.strategy = strategy;
        }
    
        public void contextMethod() {
            strategy.algorithmMethod(); //调用策略实现的方法
        }
    }
    
    class Client {
        public static void main(String[] args) {
            Strategy concreteStrategy1 = new ConcreteStrategy1(); //创建具体测策略实现
            StrategyContext strategyContext = new StrategyContext(concreteStrategy1); //在创建策略上下文的同时,将具体的策略实现对象注入到策略上下文当中
            strategyContext.contextMethod(); //调用上下文对象的方法来完成对具体策略实现的回调
        }
    }
    

    策略模式(Strategy)类图.png

    1. 策略接口角色IStrategy:用来约束一系列具体的策略算法,策略上下文角色ConcreteStrategy使用此策略接口来调用具体的策略所实现的算法。

    2. 具体策略实现角色ConcreteStrategy:具体的策略实现,即具体的算法实现。

    3. 策略上下文角色StrategyContext:策略上下文,负责和具体的策略实现交互,通常策略上下文对象会持有一个真正的策略实现对象,策略上下文还可以让具体的策略实现从其中获取相关数据,回调策略上下文对象的方法。

    1. 策略模式就是把各个平等的具体实现进行抽象、封装成为独立的算法类,然后通过上下文和具体的算法类来进行交互。
    2. 各个策略算法都是平等的,地位是一样的,正是由于各个算法的平等性,所以它们才是可以相互替换的。
    3. 虽然我们可以动态的切换各个策略,但是同一时刻只能使用一个策略

    Observer/Event:事件模式

    定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时候,所有依赖于它的对象都等到通知并自动更新

    /**
     * @author lillcol
     * 2019/6/13-23:38
     */
    //被观察者抽象类
    public abstract class Subject {
        abstract void attack(Observer observer);//添加观察者
    
        abstract void dettack(Observer observer);//移除观察者
    
        abstract void notifyObserver();//通知观察者
    
        abstract void operation();//被观察者状态变化
    }
    
    //被观察者抽象类
    abstract class AbstractSubject extends Subject {
        private List<Observer> observerList = new ArrayList<>(); //观察者对象集合
    
        @Override
        void attack(Observer observer) {//添加观察者
            observerList.add(observer);
        }
    
        @Override
        void dettack(Observer observer) {//移除观察者
            observerList.remove(observer);
        }
    
        @Override
        void notifyObserver() {
            for (Observer observer : observerList) {
                observer.update();
            }
        }
    }
    
    //被观察者实现类
    class ConcreteSubject extends AbstractSubject {
        @Override
        void operation() {
            System.out.println("ConcreteSubject 要搞事情了");
            notifyObserver();   // 通知所有观察者
        }
    }
    
    //观察者抽象类
    abstract class Observer {
        public String name;
        abstract void setName(String name);//设置名字
    
        abstract String getName();//获取名字
    
        abstract void update();//观察者更新方法
    }
    
    class ConcreteObserver1 extends Observer{
    
        @Override
        void setName(String name) {
            this.name=name;
        }
    
        @Override
        String getName() {
            return this.name;
        }
    
        @Override
        void update() {
            System.out.println("伞兵一号 ConcreteObserver1 准备就绪");
        }
    }
    
    class ConcreteObserver2 extends Observer{
    
        @Override
        void setName(String name) {
            this.name=name;
        }
    
        @Override
        String getName() {
            return this.name;
        }
    
        @Override
        void update() {
            System.out.println("伞兵二号 ConcreteObserver2 准备就绪");
        }
    }
    //测试案例:
    class Test{
        public static void main(String[] args) {
            ConcreteSubject concreteSubject = new ConcreteSubject();
            ConcreteObserver1 concreteObserver1 = new ConcreteObserver1();
            ConcreteObserver2 concreteObserver2 = new ConcreteObserver2();
            concreteSubject.attack(concreteObserver1);
            concreteSubject.attack(concreteObserver2);
            concreteSubject.operation();
            System.out.println("------");
            concreteSubject.dettack(concreteObserver1);
            concreteSubject.operation();
        }
    }
    //输出:
    ConcreteSubject 要搞事情了
    伞兵一号 ConcreteObserver1 准备就绪
    伞兵二号 ConcreteObserver2 准备就绪
    ------
    ConcreteSubject 要搞事情了
    伞兵二号 ConcreteObserver2 准备就绪
    

    观察者模式-类图.png

    其实就是发布订阅模式,发布者发布信息,订阅者获取信息;
    订阅了就能收到信息,没订阅就收不到信息。

    参考文档:李建中-(23种设计模式)
    本文为原创文章,转在请注明出处!!!!

  • 相关阅读:
    myeclipse中代码不显示SVN版本号
    java HttpURLConnection 登录网站 完整代码
    新浪微博自动(模拟)登陆详解及实现
    java模拟Cookies登陆
    paper 53 :深度学习(转载)
    paper 52 :windows7环境下theano安装
    paper 51:图像复原
    paper 50 :人脸识别简史与近期进展
    paper 49:论文退稿?审稿人帮你总结了22个能避免的常见问题
    paper 48: Latex中如何制作参考文献
  • 原文地址:https://www.cnblogs.com/lillcol/p/11129935.html
Copyright © 2020-2023  润新知