美文网首页Java设计模式
五分钟快速入门装饰、适配器、模板方法三种设计模式

五分钟快速入门装饰、适配器、模板方法三种设计模式

作者: 视野跳动 | 来源:发表于2017-12-13 16:15 被阅读14次

    前言:设计模式的概念是很抽象的,不好理解,我第一次看完这些概念也是一面懵逼,又想了想,还是一面懵逼的。在这里将概念放在前面看不懂没关系,本章的正确学习方式应该是先看《案例演示》和《代码实现》然后再回头看概念(别看概念很难理解,其实都是纸老虎,将demo敲一遍,不懂,拿刀来砍我)

    前言 :虽然有六大设计原则,二十三种设计模式,不过常见的设计模式也就那么几种,想要真正的掌握,肯定还需要我们结合具体的应用场景去练习去理解,方可应用!

    一、装饰设计模式

    • 什么是装饰设计模式?

      • 当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。这种模式就称之为装饰设计模式。
    • 装饰设计模式的优点

      • 装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。
    • Java IO流中大部分API就是通过装饰设计模式设计的

      • 例如BufferReader
    • 案例演示

      • 路人甲,一个计算机专业毕业的学生,毕业以后想找高薪水的工作。假如此时这个路人甲只会Java和 JavaWeb,无奈技术不行,于是就想去某某IT培训机构,培训一下。经过艰苦的几个月培训,路人甲终于被放出来了。路人甲抬头看了看天空,阳光有点刺眼,但是此时的路人甲已经今非昔比了,,,
    • 设计思路

      • 装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
    • 代码实现(放心是完整)

    /**
    * Project:HelloWorld
    * Package:cn.edu.java
    * Author:SKFsky
    * CreateTime:2017/12/13 14:11
    * Description: 装饰设计模式
    */
    public class Demo_Decorator {
       public static void main(String[] args) {
           //大学毕业时的路人甲
           System.out.println("大学毕业时的路人甲:");
           LuRenJia luRenJia = new LuRenJia();
           luRenJia.code();
           System.out.println();
           //经过特训后的路人甲
           System.out.println("经过特训后的路人甲:");
           Trainning train = new Trainning(new LuRenJia());
           train.code();
       }
    }
    
    interface Coder {
       public void code();
    }
    
    class LuRenJia implements Coder{
       @Override
       public void code() {
           System.out.println("我会Java");
           System.out.println("我会JavaWeb");
       }
    }
    
    class Trainning implements Coder {
    
       private LuRenJia lurenjia;   //获取到被包装的类的引用
       public Trainning(LuRenJia lurenjia){   //通过构造函数创建对象的时候,传入被包装的对象
           this.lurenjia = lurenjia;
       }
    
       @Override
       public void code() {      //对其原有功能进行升级
           lurenjia.code();
           System.out.println("我学会了数据库");
           System.out.println("我学会了Kotlin");
           System.out.println("我学会了设计模式");
           System.out.println("我学会了一阳指");
           System.out.println("我学会了一目千行");
           System.out.println("我学会了做笔记");
           System.out.println("我学会了.....");
       }
    }
    
    • 结果展示


      我是大侠路人甲
    • 再举一个例子

      • 比如人吃饭,路人乙刚毕业的时候是一个穷大学生,因为穷,每天中午只能吃两个大馍(只能吃两个哦,吃多了,你还是好好想想晚上怎么办吧),路人乙每天也没有别的想法,简简单单的吃馍。可是有一天路人乙通过,,,,,有钱了,那么路人乙每天中午不仅可以吃烤鸡、烤鸭、烤炉猪,还可以吃兰州拉面了。原来只是简单的吃饭,通过,,,,,以后就可以不简单的吃饭了。通过了什么,当然是一个装饰者(中彩票)。自己实现去吧。
      • 分享一则最近看到中彩票的一个笑话:Adode公司发布了一个问卷调查假如彩票中500万你会怎么用?(另外上海局部房价突破每平方米34万元,当然这和我们的故事没有关系,哈哈)。路人乙中了500万彩票。以前,中了500万彩票,当然是先买一个房子啦,然后再买一个车子,最后剩下的钱就去旅行。现在,中了500万彩票,当然也是先买一个房子啦,剩下的钱,当然是慢慢换房贷!

    二、适配器设计模式

    • 什么是适配器?

      • 在使用监听器的时候, 需要定义一个类事件监听器接口.
      • 通常接口中有多个方法, 而程序中不一定所有的都用到, 但又必须重写, 这很繁琐.
      • 适配器简化了这些操作, 我们定义监听器时只要继承适配器, 然后重写需要的方法即可.
    • b.适配器原理

      • 适配器就是一个类, 实现了监听器接口, 所有抽象方法都重写了, 但是方法全是空的.
      • 适配器类需要定义成抽象的,因为创建该类对象,调用空方法是没有意义的.
      • 目的就是为了简化程序员的操作, 定义监听器时继承适配器, 只重写需要的方法就可以了.
    • 案例演示

      • 我们知道一般的和尚每天都需要打坐,念经,习武,但是每个和尚的性格都不一样,不可能所有的和尚都是千篇一律的,就像唐僧和鲁智深,就是完全不同的两个和尚。每个和尚都是独立的,我们也不能要求每个和尚都是一模一样的,所以我们需要有一个中间类,让每个人有自己的个性。
    • 设计思路

      • 定义一个接口
      • 定义一个抽象类实现所有的接口
      • 别的类继承这个抽象类即可,我们管这个抽象类的名字叫适配器
    • 代码实现

    
    /**
     * Project:HelloWorld
     * Package:cn.edu.java
     * Author:SKFsky
     * CreateTime:2017/12/13 15:10
     * Description: 适配器设计模式
     */
    public class Demo_Adapter {
        public static void main(String[] args) {
            tangtang tang = new tangtang();
            tang.dazuo();
            tang.nijing();
            luzhishen lu = new luzhishen();
            lu.xiwu();
            lu.chirou();
            lu.dajia();
        }
    }
    
    //和尚接口
    interface HeShang{
        public void nijing();//念经
        public void dazuo();//打坐
        public void paobu();//跑步
        public void xiwu();//习武
    }
    
    //适配器,实现了接口,并且定义成抽象类型的类了(抽象的类不能被实例化),这里面的方法都是空的,不需要去实现
    abstract class Adapter implements HeShang{
    
        @Override
        public void nijing() {
    
        }
    
        @Override
        public void dazuo() {
    
        }
    
        @Override
        public void paobu() {
    
        }
    
        @Override
        public void xiwu() {
    
        }
    }
    
    //唐僧
    class tangtang extends Adapter {
    
        @Override
        public void nijing() {
            System.out.println("我是唐僧我喜欢念经");
        }
    
        @Override
        public void dazuo() {
            System.out.println("我是唐僧我喜欢打坐");
        }
    }
    
    //鲁智深,我们的知道他是一个花和尚,喜欢习武,吃酒吃肉
    class luzhishen extends Adapter {
    
        @Override
        public void xiwu() {
            System.out.println("我是鲁智深我喜欢习武");
        }
    
        public void chirou() {
            System.out.println("我是鲁智深我喜欢吃肉");
        }
    
        public void dajia() {
            System.out.println("我是鲁智深我喜欢打架");
        }
    }
    
    • 结果展示


      东游记
    • 总结
      • 这样继承自适配器的类,可以实现父类方法,同时也可以有自己扩展的方法。

    三、模板方法设计模式

    • 什么是模板方法设计模式?

      • 模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现
    • 优点

      • 使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求
    • 缺点

      • 如果算法骨架有修改的话,则需要修改抽象类
    • 案例演示

      • 设计一个模板,用了计算我们执行某一个方法所要的时间
    • 设计思路

      • Java是面向对象的编程,定义一个类,实现模板的方法
      • 子类继承这个类实现相关的方法
    • 代码实现

    /**
     * Project:HelloWorld
     * Package:cn.edu.java
     * Author:SKFsky
     * CreateTime:2017/12/13 15:42
     * Description: 模板方法设计模式
     */
    public class Demo_Template {
        public static void main(String[] args) {
            Demo demo = new Demo();
            long time = demo.getTime();
            System.out.println(time);
        }
    }
    
    //定义成抽象类,因为定义了一个抽象方法code()
    abstract class GetTime {
        //用final关键字修饰,因为该方法是一个模板,不希望让子类重写。但是可以被子类调用。计算code方法的执行时长
        public final long getTime() {
            long start = System.currentTimeMillis();
            code();
            long end = System.currentTimeMillis();
            return end - start;
        }
    
        //定义成抽象的,在子类中去实现
        public abstract void code();
    }
    
    class Demo extends GetTime{
        
        @Override
        public void code() {
            int i = 0;
            while (i<100000) {
                System.out.println("x");
                i++;
            }
        }
    }
    
    • 结果展示


      毫秒

    相关文章

      网友评论

        本文标题:五分钟快速入门装饰、适配器、模板方法三种设计模式

        本文链接:https://www.haomeiwen.com/subject/sypaixtx.html