zoukankan      html  css  js  c++  java
  • 面向对象设计模式原则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 }
  • 相关阅读:
    linux 内存映射-ioremap和mmap函数
    vue 模板语法-插值的操作(12-22)
    chrome浏览器json插件
    vue初识(1-11)2020-10-27
    后盾人:JS课程第一章(11-18)2020-10-25
    博客园美化
    chrome 设置自动刷新网页
    二叉树的层次遍历
    poj 2905 双向队列(待补充)
    poj 2159 D
  • 原文地址:https://www.cnblogs.com/asenyang/p/11758431.html
Copyright © 2011-2022 走看看