• 面向对象设计模式原则03 依赖倒置原则(DIP)


    依赖倒置原则(Dependence Inversion Principle,DIP)的原始定义为:高层模块不应该依赖低层模块,两者都应该依赖其抽象;

    抽象不应该依赖细节,细节应该依赖抽象。

    其核心思想是:要面向接口编程,不要面向实现编程。

    依赖倒置原则的目的是通过要面向接口的编程来降低类间的耦合性,所以我们在实际编程中只要遵循以下4点,就能在项目中满足这个规则。

    1.每个类尽量提供接口或抽象类,或者两者都具备。

    2.变量的声明类型尽量是接口或者是抽象类。

    3.任何类都不应该从具体类派生。

    4.使用继承时尽量遵循里氏替换原则

    下面给出一个具体的例子进行说明。

    UML类图:

     

    有三种方式可以实现依赖倒置:

    方式1:使用接口传递,QQPlayer实现了IPlayerA,而IPlayerA依赖于IFile,这样通过IPlayerA将IFile传递给了QQPlayer类的对象。

    方式2:使用构造函数,NEPlayer实现了IPlayerB,并且NEPlayer关联IFile (实线箭头),通过构造函数将IFile的实例传递给NEPlayer类的对象。

    方式3:使用属性Setter方法,KWPlayer实现了IPlayerB,并且KWPlayer关联IFile (实现箭头),通过私有变量的Setter方法setFile(),将IFile实例传递给KWPlayer类的对象。

    下面是根据UML类图实现的Java代码:

     1 public interface IFile {
     2     public String getFileName();
     3 }
     4 
     5 public class MusicFile implements IFile {
     6 
     7     private String fileName;
     8 
     9     public MusicFile(String fileName) {
    10         this.fileName = fileName;
    11     }
    12 
    13     @Override
    14     public String getFileName() {
    15         return this.fileName;
    16     }
    17 
    18 }
    19 
    20 public interface IPlayerA {
    21     public void playFile(IFile file);
    22 }
    23 
    24 public interface IPlayerB {
    25     public void play();
    26 }
    27 
    28 public class QQPlayer implements IPlayerA {
    29     @Override
    30     public void playFile(IFile file) {
    31         String fileName = file.getFileName();
    32         System.out.println("QQ音乐开始播放歌曲:" + fileName);
    33     }
    34 }
    35 
    36 public class NEPlayer implements IPlayerB {
    37     private IFile file;
    38 
    39     public NEPlayer(IFile file) {
    40         this.file = file;
    41     }
    42 
    43     @Override
    44     public void play() {
    45         String fileName = this.file.getFileName();
    46         System.out.println("网易音乐开始播放歌曲:" + fileName);
    47     }
    48 }
    49 
    50 public class KWPlayer implements IPlayerB {
    51 
    52     private IFile file;
    53 
    54     public void setFile(IFile file) {
    55         this.file = file;
    56     }
    57 
    58     @Override
    59     public void play() {
    60         // TODO Auto-generated method stub
    61         String fileName = this.file.getFileName();
    62         System.out.println("酷我音乐开始播放歌曲:" + fileName);
    63     }
    64 }
    65 
    66 public class Client {
    67     public static void main(String[] args) {
    68         byInterface();
    69         byConstruct();
    70         bySetter();
    71     }
    72 
    73     // 方式1:接口方式
    74     public static void byInterface() {
    75         IFile file = new MusicFile("盗将行");
    76         QQPlayer player = new QQPlayer();
    77         player.playFile(file);
    78     }
    79 
    80     // 方式2:构造函数方式
    81     public static void byConstruct() {
    82         IFile file = new MusicFile("出山");
    83         NEPlayer player = new NEPlayer(file);
    84         player.play();
    85     }
    86 
    87     // 方式3:属性Setter方式
    88     public static void bySetter() {
    89         IFile file = new MusicFile("芒种");
    90         KWPlayer player = new KWPlayer();
    91         player.setFile(file);
    92         player.play();
    93     }
    94 }
  • 相关阅读:
    iOS设计模式之观察者模式
    iOS设计模式之装饰者模式
    【Dart学习】--之Iterable相关方法总结
    【Dart学习】--之Duration相关方法总结
    【Flutter学习】基本组件之弹窗和提示(SnackBar、BottomSheet、Dialog)
    【Dart学习】--Dart之超级父类之Object
    从零开始实现ASP.NET Core MVC的插件式开发(五)
    从零开始实现ASP.NET Core MVC的插件式开发(四)
    从零开始实现ASP.NET Core MVC的插件式开发(三)
    从零开始实现ASP.NET Core MVC的插件式开发(二)
  • 原文地址:https://www.cnblogs.com/asenyang/p/11758431.html
Copyright © 2020-2023  润新知