• 设计模式的六大原则


    一、设计模式的概念及作用

      设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。

    二、六大原则

    1.单一职责原则(Single Responsibility Principle,简称SRP)

      1) 概念:一个类只负责一项职责。

      2) 举例说明:假设有一个接口,如下:

     1   // 用户接口
     2   public interface IUser{
     3       // 连接数据库方法
     4       public Connection getConnection();
     5       // 查询用户
     6       public User qryUser(User user);
     7       // 增加用户
     8       public int addUser(User user);
     9   }

      当操作数据库的信息改变的时候,需要修改大量的代码,所以,可以将操作数据库的方法抽离出来,将上面的用户接口改为:

     1     // 数据库操作类
     2     public class DBUtil{
     3         // 连接数据库方法
     4         public static Connection getConnection(){....}
     5     }
     6 
     7     // 用户接口
     8     public interface IUser{
     9         // 查询用户
    10         public User qryUser(User user);
    11         // 增加用户
    12         public int addUser(User user);
    13     }
    14 
    15     // 用户实现类
    16     public class UserImpl{
    17         Connection connection = null;
    18         // 查询用户
    19         public User qryUser(User user){
    20             connection = DBUtil.getConnection();
    21             ....
    22         }
    23         // 增加用户
    24         public int addUser(User user){
    25             connection = DBUtil.getConnection();
    26             ....
    27         }
    28     }

      即,用户接口中只操作用户的基本信息,不操作数据库。若要需要使用数据库操作,将数据库操作抽离出来,降低代码的耦合性。

      3) 优点:类的复杂度降低、可读性提高、可维护性提高、扩展性提高、降低了变更引起的风险。

    2.里氏替换原则(Liskov Substitution Principle,简称LSP)

      之所以叫里氏替换原则1988年,是因为该原则是由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的。

      1) 概念:所有引用父类的地方必须能 透明使用子类,反过来 不成立。

      2) 举例说明:

         喜欢动物 = 喜欢狗,因为动物中 包含狗,等式是成立的。

         喜欢狗 != 喜欢动物。 

            class Animal{}
            class Dog extends Animal{}

      3) 优点:增强程序的健壮性,即使增加了子类,原有的子类还可以继续运行。

    3.依赖倒置原则(Dependence Inversion Principle,简称DIP)

      1) 概念:依赖倒置原则的本质就是通过抽象(接口或抽象类)使个各类或模块的实现彼此独立,互不影响,实现模块间的松耦合。

      2)举例说明:假设有一个CD唱片,CD唱片的播放 需要 CD播放机,即:

     1     // CD
     2     class CDRom{
     3         public void play(){
     4             System.out.println("play CDRom");
     5         }
     6     }
     7     
     8     // CD播放机
     9     class Player{
    10         public void start(CDRom cd){
    11             System.out.println("CD playing ...");
    12             cd.play();
    13         }
    14     }
    15     
    16     // 测试方法
    17     public class Main{
    18         public static void main(Stirng[] args){
    19             Player player = new Player();
    20             CDRom cd = new CDRom();
    21             player.start(cd);
    22         }
    23     }

      随着科技的发达,DVD出现了,这时候就需要DVD播放机了,如下:

     1     // DVD
     2     class DVDRom{
     3         public void play(){
     4             System.out.println("play DVDRom");
     5         }
     6     }
     7     
     8     // DVD播放器
     9     class Player{
    10         public void start(CDRom cd){
    11             System.out.println("DVD playing ...");
    12             cd.play();
    13         }
    14     }

      又随着科技的发达,MP3、MP4等问世,这时候我们又需要定义更多的类,这样子会很繁琐,所以,可以定义一个上层接口,让下层的类去实现,将上面的代码 改为 如下:

     1     // 媒体接口
     2     inteferce Media{        // cd,dvd,mp3,mp4.mp5...
     3         public void play();
     4     }
     5     
     6     // DVD,并实现媒体接口
     7     class DVDRom impl Media{
     8         public void play(){
     9             System.out.println("play DVDRom");
    10         }
    11     }
    12     
    13     // CD,并实现媒体接口
    14     class CDRom impl Media{
    15         public void play(){
    16             System.out.println("play CDRom");
    17         }
    18     }
    19     
    20     // 通用播放机
    21     class Player{
    22         public void start(Media media){
    23             System.out.println("playing ...");
    24             media.play();
    25         }
    26     }
    27     
    28     // 测试方法
    29     public class Main{
    30         public static void main(Stirng[] args){
    31             Player player = new Player();
    32             media cd = new CDRom();
    33             
    34             media dvd = new DVDRom();
    35             player.start(dvd);
    36         }
    37     }

      3) 优点:在小型项目中很难体现出来。但在大中型项目中可以减少需求变化引起的工作量,使并行开发更友好。

    4.接口隔离原则(Interface Segregation Principle,简称ISP)

      1.概念:类间的依赖关系应该建立在最小的接口上。

         可以理解为:建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。也就是说,我们要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。

         一句话概括:一个接口中不要什么事情都去做,其实什么事情都做不好。

      2.举例说明:

     1     // 灯接口
     2     interface light{
     3         // 开灯方法
     4         on();
     5         // 关灯方法
     6         off();
     7         // 维修方法
     8         repare(); 
     9         // 开电视方法
    10         turnOnTV();  
    11     }

      上面的灯接口中,既有灯的方法,又有工作人员的接口,又有电视的接口,这样 一个接口就会显得很臃肿,很庞大。

      运用接口隔离原则之后,将接口细化,分散为多个接口,可以预防外来变更的扩散。如下:

     1     // 灯接口
     2     interface light{
     3         // 开灯方法
     4         on();
     5         // 关灯方法
     6         off();
     7     }
     8     
     9     // 电视接口
    10     intefece tv{
    11         // 开电视接口
    12         on();
    13         // 关电视接口
    14         off();
    15     }
    16     
    17     // 工作人员
    18     intefece worker{
    19         // 维修
    20         repaire();
    21     }

      3.优点:通过分散定义多个接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。

    5.迪米特法则(Law of Demeter,简称LoD)

      1.概念:类间解耦。

      2.问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。

      3.注意点:迪米特法则的初衷是降低类之间的耦合,由于每个类都减少了不必要的依赖,因此的确可以降低耦合关系。但是凡事都有度,虽然可以避免与非直接的类通信,但是要通信,必然会通过一个“中介”来发生联系。过分的使用迪米特原则,会产生大量这样的中介和传递类,导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。

    6.开闭原则(Open Close Principle,简称OCP)

      1). 思想:尽量通过扩展软件实体来解决需求变化,而不是通过修改已有的代码来完成变化。

      2). 开:对扩展开放

          关:对修改关闭

      总结:单一职责原则告诉我们实现类要职责单一;

         里氏替换原则告诉我们不要破坏继承体系;

           依赖倒置原则告诉我们要面向接口编程;

           接口隔离原则告诉我们在设计接口的时候要精简单一;

               迪米特法则告诉我们要降低耦合;

           开闭原则是总纲,他告诉我们要对扩展开放,对修改关闭。  

  • 相关阅读:
    android 4.0 中出错 java.lang.UnsupportedOperationException
    怎么确定你的CPU是否支持64位虚拟化
    宽度百分比单位的转换公式
    Test SRM Level Three: LargestCircle, Brute Force
    802.11(wifi)的MAC层功能
    zookeeper集群的python代码测试
    mysqldump 命令的使用
    xp硬盘安装Fedora14 过程记录及心得体会(fedora14 live版本680M 和fedora14 DVD版本3.2G的选择)
    ContentProvider的使用
    基于 Java 2 运行时安全模型的线程协作--转
  • 原文地址:https://www.cnblogs.com/xbq8080/p/6831949.html
Copyright © 2020-2023  润新知