• 浅谈设计模式的学习(上)


    作为一个开发人员,能写出一个漂亮可扩展的代码,绝对是一件令人愉快的事情。那设计模式就是一门必修课!

      本文就自己学习设计模式的一点经历做一个记录。

      本人在读大学时,为了学习设计模式就买了一本《java与模式》的数据,书籍有一千多页很重、而且价格不菲。没办法,花那么多钱买的不看岂不浪费。于是每天早上读一章,坚持几个月我终于读完了。这几个月真是煎熬啊,几个月下来,回忆一下似乎自己真得也没收获到什么,很悍然啊。难道是书籍不好吗还是我读的不认真?其实在我现在看来都不是。而为什么读完了却什么也没收获到呢?我觉着:第一是因为我当时编码的经历不够丰富、第二没有理解设计模式的用途和思想。所以学了有点白学。至于编码经验这个只能靠自己多练习,没什么好说的。这里就说说我对设计模式学习的一点理解吧

      1、学习设计模式,首先要理解设计模式到底是什么。

           曾经我一度认为,一个设计模式就是一个固定结构的代码,比如观察者模式,就是在一个被观察者里边维护一个集合,将观察者放进这个集合里,一有事件触发便遍历集合里的观察者调用他们的某个方法。(如果你也这么理解,那赶快收手吧,否则你会很痛苦的)这么理解对吗?至少我现在认为是打错特错的。总共有23种设计模式,是不多,但是如果把每个设计模式理解成一个代码结构的话肯定会很乱,因为有好多设计模式代码结构很相似,比如代理模式和装饰者模式,这么理解只会让你混乱搞不清楚,你认为呢?。那我们该怎么理解设计模式呢,个人觉着哈,一个设计模式是针对的一个应用场景,比如代理模式和装饰模式,代码结构很相似,但是代理模式的用途是为了添加别的功能,比如spring的aop就是代理模式的一个很好地应用,项目中有很多数据库操作,但是无论是曾、删、改操作前都要打开事务,操作后要提交事务,所以采用代理,将这打开和关闭事务统一管理,这就是相当于在增删改操作前后添加了别的操作;而装饰模式呢,他是加强和装饰某一个已有的功能,最经典的应用就是jdk里的输入输出流了,比如BufferedInputStream就是给InputStream加强了基于缓存读写数据流的功能。所以这里我再强调一遍,设计模式是针对不同的应用场景而不是一个代码结构(千万不要通过代码结构去区分不同的设计模式,就像前边说的代理和装饰,代码结构相似,但是应用目的是不同的)。切记其珍惜啊

    2、学习设计模式,首先要清楚设计模式能干什么。

         学习设计模式,你需要心里认可他,但是对于很多像我一样的一些初学者吧,因为体会不到他的好处,心里就没有去认可他,所以也无从踏心的去学习了。设计模式有什么好处呢?能干什么呢?在这里我举个例子:(希望你看了也能有所感触)

         我们经常要遍历一个集合,这个集合可能是ArrayList也可能是LinkedList,学过数据结构的都知道这两个集合的数据结构是不同的,数据结构不同,所以遍历方式肯定也不同,这样现实开发中你要记住每一个数据结构的遍历方式,如果数据结构更多,那岂不是很累啊(相信你会赞同吧)。但是现实中你遍历集合,因为集合数据结构的不同而采用不同的遍历方式了吗?肯定没有吧,无论是基于数组还是链表的集合,我们用一个Iterator搞定,你只需要在意iterator的两个方法(hasNext()和next())而不必理会集合的内部数据结构。简单吧,爽吗,反正我是感觉很爽,这就是设计模式的一个好处。这里采用的什么设计模式呢?不知道能想到吗,工厂方法模式。ArrayList和LinkedList作为工厂生产自己的Iterator,因为只有自己了解自己内部数据结构和遍历方式。这里他们创建的迭代器都实现了Iterator接口,我们是针对的接口编程,所以体会不到不同集合创建的迭代器的不同。(现在你是否认可了设计模式啊,是否认识到他是有用的呢,如果因为这篇文章让你认可了它,真是我的荣幸啊,哈哈)

      上边这个例子可以说是设计模式能够封装变化,让客户端调用(就是你调用你用设计模式编写的类的地方,比如main方法里)不受变化的影响;下边我再举个例子,说一下设计模式另一个能干的事------对方便扩展(就是开闭原则)

        大家知道开关和灯泡,开关都有一个打开关闭的功能,无论你是声控开关还是其他各种类型的开关;灯泡都有一个亮和灭的功能,无乱你是白炽灯、闪关灯的。这样我们可以分别为灯泡和开关提取一个接口,灯泡接口和开关接口,灯泡接口提供亮和灭方法,开关提供开和关方法。代码如下:

    快关接口:

    public interface Switch {
    
        public void setLight(Light light);
    
        public void open();
    
        public void close();
    }
    1 public interface Light {
    2 
    3     public void lightUp();
    4     
    5     public void LightOff();
    6 }

    在这里我们再提供一个普通的快关实现:

     1 public class NormalSwitch implements Switch{
     2 
     3     private Light light;
     4     
     5     public void setLight(Light light){
     6         this.light=light;
     7     }
     8     
     9     @Override
    10     public void open() {
    11         light.lightUp();
    12     }
    13     
    14     @Override
    15     public void close() {
    16         light.LightOff();
    17     }
    18 }

    这是一个普通的灯泡实现:

    public class NormalLight implements Light {
    
        @Override
        public void lightUp() {
            System.out.println("灯亮了");
        }
    
        @Override
        public void LightOff() {
            System.out.println("灯灭了");
        }
    
    }

    接下来是客户端的调用了:

    public class Main {
    
        public static void main(String[] args) {
            Light light = new NormalLight();
    
            Switch swtich= new NormalSwitch();
    
            swtich.setLight(light);
    
            swtich.open();
    
            swtich.close();
        }
    
    }

    接下来说一说这么做如何有利于扩展了,比如我要换灯泡了,换个高端大气上档次的:

     1 public class LuxuriousLight implements Light {
     2 
     3     @Override
     4     public void lightUp() {
     5         System.out.println("灯泡豪华的亮了");
     6     }
     7 
     8     @Override
     9     public void LightOff() {
    10         System.out.println("灯泡骄傲的灭了");
    11     }
    12 
    13 }

    对于客户端要怎么变化呢?来吧看一看:

     1 public class Main {
     2 
     3     public static void main(String[] args) {
     4         Light light = new LuxuriousLight();//NormalLight();
     5 
     6         Switch swtich= new NormalSwitch();
     7 
     8         swtich.setLight(light);
     9 
    10         swtich.open();
    11 
    12         swtich.close();
    13     }
    14 
    15 }

    看,我们之前的普通灯泡没有收到任何影响吧,如果还有别的客户端使用了普通的灯泡,我们新添加的奢侈的灯泡绝对不会影响到他们的逻辑。当然有朋友可能会说,客户端不也是把new NormalLight改成了new LuxuriousLight了吗,呵呵,这点改动不无妨,主要是我们后边通过开关关闭点灯的逻辑没有变化。这无论是应对变化还是可扩展性都是很有帮助的。在这里不知道你想到了这是什么设计模式吗?没错,就是桥接模式,简单吧。

      学习设计模式有一点特别特别重要的一点,就是抽象思维,这是整个设计模式的基石,由于时间原因,下次再续。O(∩_∩)O~

      作为程序员,身体是一切的根本,注意身体健康,五一快乐哦

     

  • 相关阅读:
    Java程序员极力推荐的springboot全家桶干货系列——收藏必会系列
    mysql 远程连接数据库的二种方法
    mysql取以当前时间为中心的任意时间段的时间戳
    使用sql语句,查询 mysql 的安装地址
    MyEclipse中点击Deploy MyEclipse J2EE Project to Server无响应解决方法
    使用DOS访问数据库详解
    mysql查询字段为null 返回0
    MySQL触发器Trigger实例篇
    JAVA汉字转拼音(取首字母大写)
    阿里云上传文件
  • 原文地址:https://www.cnblogs.com/metoy/p/3702549.html
Copyright © 2020-2023  润新知