• 用最简单的例子说明设计模式(二)之模版方法、策略模式、组合模式、观察者模式


    模板方法模式
    提供一个抽象类,将部分逻辑以具体方法或构造器的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法(多态实现),从而实现不同的业务逻辑。
     
    使用场景
    1)多个子类有公有的方法,并且逻辑基本相同时
    2)重要、复杂的算法,可以把核心算法设计为模板方法
    3)重构时,模板方法模式是一个经常使用的模式
    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 BossWork extends AbstractWork {
         
        @Override
        protected void goToWork() {
            System.out.println("老板开车去上班");
        }
     
        @Override
        protected void work() {
            System.out.println("老板的分配工作给员工");
        }
     
        @Override
        protected void getOffWork() {
            System.out.println("老板开车去下班");
        }
     
    }
    
    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("员工做公交下班");
        }
     
    }
    
    public class Test {
        public static void main(String[] args) {
            BossWork bossWork = new BossWork();
            StaffWork staffWork = new StaffWork();
            bossWork.newDay();
            System.out.println("------------------------");
            staffWork.newDay();
        }
    }
    

      

     
     
    策略模式
    定义了算法家庭,分别封装起来。让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
     一个类定义了多种行为,并且这些行为在这个类的方法中以多个条件语句的形式出现,那么可以使用策略模式避免在类中使用大量的条件语句。
     
     
    public interface AbstractStrategy {
        //按距离来计算价格
        int calculatePrice(int km);
    }
    
    public class BusStrategy implements AbstractStrategy {
        @Override
        public int calculatePrice(int km) {
            int extraTotal = km - 10;
            int extraFactor = extraTotal / 5;
            int fraction = extraTotal % 5;
            int price = 1 + extraTotal % 5;
            return fraction > 0 ? ++price : price;
        }
    }
    
    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));
        }
    
    }
    

    传统写法

        //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;
            }
        }
    

      

     

    组合模式
    使用户对单个对象和组合对象的使用具有一致性。将对象组合成树形结构以表示“部分-整体”的层次结构。
    Component : 组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。
    Leaf : 表示叶节点对象。叶子节点没有子节点。
    Composite : 定义枝节点行为,用来存储子部件,在 Component 接口中实现与子部件相关的操作。例如 Add 和 Remove
     
    public abstract class File {
    
        private String name;
    
        public File(String name) {
            this.name = name;
        }
    
        //操作方法
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public abstract void watch();
    
        //组合方法
        public void add(File file) {
            throw new UnsupportedOperationException();
        }
    
        public void remove(File file) {
            throw new UnsupportedOperationException();
        }
    
        public File getChild(int position) {
            throw new UnsupportedOperationException();
        }
    }
    
    public class Folder extends File {
    
        private List<File> mFileList;
    
        public Folder(String name) {
            super(name);
            mFileList = new ArrayList<>();
        }
    
        @Override
        public void watch() {
            StringBuffer fileName = new StringBuffer();
            for (File file : mFileList) {
                fileName.append(file.getName() + ";");
            }
           
              System.out.println("组合模式:这是一个叫" + getName() + "文件夹,包含" + mFileList.size() + "个文件,分别是:" + fileName);
    
        }
    
        @Override
        public void add(File file) {
            mFileList.add(file);
        }
    
        @Override
        public void remove(File file) {
            mFileList.remove(file);
        }
    
        @Override
        public File getChild(int position) {
            return mFileList.get(position);
        }
    }
    
    public class TextFile extends File {
    
        public TextFile(String name) {
            super(name);
        }
    
        @Override
        public void watch() {
            System.out.println("组合模式:这是一个叫" + getName() + "文本文件");
        }
    }
    
    public class testComposite {
        public static void main(String[] strings) {
            TextFile textFileA = new TextFile("a.txt");
            TextFile textFileB = new TextFile("b.txt");
            TextFile textFileC = new TextFile("c.txt");
    
            textFileA.watch();
        //  textFileA.add(textFileB);//调用会抛我们在抽象接口中写的异常
    
            Folder folder = new Folder("学习资料");
            folder.add(textFileA);
            folder.add(textFileB);
            folder.add(textFileC);
            folder.watch();
            folder.getChild(1).watch();
            
            Folder folder1 = new Folder("个人资料");
            folder1.add(textFileA);
            folder1.add(textFileB);
            //可以随便组合
            Folder folder2 = new Folder("D盘资料");
            folder2.add(folder);
            folder2.add(folder1);
          
        }
    
    }
    

      

     
     
    观察者模式
    定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆可得到通知并被自动更新。
    观察者模式在android中的实际运用:回调模式
    回调模式:实现了抽象类/接口的实例实现了父类的提供的抽象方法后,将该方法交还给父类来处理。
    例如:通过 setOnClickListener() 方法,Button 持有 OnClickListener 的引用(这一过程没有在图上画出);当用户点击时,Button 自动调用 OnClickListener 的 onClick() 方法。另外,如果把这张图中的概念抽象出来(Button(view) -> 被观察者、OnClickListener -> 观察者、setOnClickListener() -> 订阅,onClick() -> 事件),就由专用的观察者模式(例如只用于监听控件点击)转变成了通用的观察者模式。
     
    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");
        }
    }
    

      

     

    相关源码:

    https://github.com/peiniwan/DesignPattern.git
     
     
  • 相关阅读:
    setHapticFeedbackEnabled在androi的作用
    Android 跑马灯
    jQuery中绑定事件的命名空间详解
    可见即所得的CSS编辑设计
    盘点8种CSS实现垂直居中水平居中的绝对定位居中技术
    用到的知识点
    用PS去除图片中文字的6个方法
    html页面头部里的meta
    px pt em对应关系
    phpMyAdmin安装与配置(涉及LAMP配置)
  • 原文地址:https://www.cnblogs.com/sixrain/p/8717071.html
Copyright © 2020-2023  润新知