IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java-设计模式【之】 有道有术(设计原则,代码示例,看完必会) -> 正文阅读

[Java知识库]Java-设计模式【之】 有道有术(设计原则,代码示例,看完必会)

名词解析

  • 高内聚,低耦合、可读性、可扩展性、可维护性、代码重用性
  • 高内聚,低耦合
    类与类之间必然会存在交互,当存在互相依赖和调用的时候,尽量满足
    高内聚 :(类、功能)自身各种属性与方法的紧密联系
    低耦合 :(类、功能)与外部交互时的少量联系,只通过几个方法函数,进行交互
  • 可读性
    编写代码遵守一定规范,容易阅读与理解。
    比如:不要使用过长的链式调用,要添加必要的注释信息,遵守Java标识符命名规范,或者公司内部统一开发规范
  • 可扩展性
    对于新增的功能,不会影响到已经存在的功能,并且容易添加
    比如:新增一个特殊的解析JSON的独立工具类,只需要实现已经存在的JSON接口,并新增一个特殊方法。代码中只需要修改引用类型即可。
  • 可维护性(可读性+可扩展性)
  • 代码重用性
    同一功能的代码,不需要重新编写,只需要稍加改动即可
    比如:封装工具方法,或者打成jar包,引入使用

1.单一职责

  • 单一职责
    (功能模块、类、接口、函数)创建的目的性要明确清晰,只是为了实现某一种 或 某一类的职责。
  • 个人理解
    1.单一职责的类,只为处理职责以内的问题,代码相对会容易理解
    2.降低变更风险,提高可维护性
    3.虽然是职责单一,但是未必只能有一个类。也可以是方法层面的单一职责,也可以是多个类实现一个职责。

2.接口隔离

  • 接口隔离
    实现特定功能所需的多种职责接口,应按照职责划分,各个接口之间应该独立存在,(尽量)不要有关联关系
  • 个人理解
    对单一职责的再次强调,接口的设计,需要合理的规划与拆分,满足低耦合标准。

3.依赖倒置(面向接口编程)

  • 依赖倒置原则
    1.依赖倒置的原则核心就是 面向接口编程
    2.低层模块依赖高层模块
    3.细节依赖抽象
  • 个人理解
    对于一个功能的实现,细节过于繁琐,抽象后会结构清晰
    按照抽象的结构 以抽象为基础,实现后的代码 容易理解、结构清晰,
    • 如:画出UML类图,指定接口名与内部应具备的函数方法,指出依赖关系,把代码实现分发给其他人去完成
    • java中:抽象指的是接口(interface)或抽象类(abstract),细节就是具体的实现类
  • 注意
    1.低层模块,尽量实现抽象类或接口,这样程序稳定性更好.
    2.变量,尽量使用抽象类或接口最为类型声明, 利于程序扩展

4.里氏替换

  • 里氏替换原则
    子类继承父类后,尽量不要重写父类的方法。
    推荐使用 聚合、组合、引用,来达到目的。
  • 理解
    通常在继承以后,重写父类的方法完成新的功能
    这样写起来简单,但复用性会比较差,会增加代码的耦合性。

  • 如果:子类继承父类时,如果存在一个父类,多个子类
    1.变量引用:子类引用了父类定义的变量,父类修改变量后,全部子类将出现变更
    2.方法引用:子类引用了父类定义的方法,父类修改方法后,全部子类将出现变更
    3.变量重写:子类重写父类变量,多个子类间,同一变量会不相同
    4.方法重写:子类重写父类方法,多个子类间,同一方法会不相同

  • 推荐使用 聚合、组合、引用,来达到目的。

5.开闭原则

  • 开闭原则(ocp原则)
  • 用抽象构建框架结构,用实现扩展细节(面向接口编程)
  • 增加新功能的时候,尽量不修改代码,或者尽可能少修改代码
  • 开:对扩展开放。(新增功能、代码、函数)
  • 闭:对修改关闭。(改动旧功能、代码、函数)
  • 理解
    本质上还是强调,面向接口编程,当考虑到扩展的情况,首先抽象出功能接口
    当真的出现扩展时,新写一个实现类就可以了,源代码不需要改变

6.迪米特(好朋友原则)

  • 迪米特原则(最少知道原则)
    1.类与类之间做到,最少的交互
    2.逻辑封装在类的内部,对外只提供简单的方法
    3.迪米特法则的核心是降低类之间的耦合
    4.迪米特法则只是要求降低,并不是要求完全没有依赖关系

  • 尽量与直接的朋友通信
    一个类,不应该以局部变量的形式出现在其他类中

  • 直接朋友:成员变量,方法参数,方法返回值
  • 陌生朋友:以局部变量的形式,出现的其他类。
//外部类 A
class A {
}

//外部类 B
class B {
}

//调用类Start
public class Start {
    //a:直接朋友(成员变量)
    A a = new A();
    //b:直接朋友(成员变量)
    B b = new B();

    //paramA:直接朋友(参数)
    public A test(A paramA) {

        //_a_:陌生朋友(局部变量,外部类)
        A _a_ = new A();

        //paramA:直接朋友(返回值)
        return paramA;
    }

    //paramB:直接朋友(参数)
    public B test(B paramB) {

        //_b_:陌生朋友(局部变量,外部类)
        B _b_ = new B();

        //paramB:直接朋友(返回值)
        return paramB;
    }

}

7.合成复用

  • 合成复用原则
    功能设计与实现的过程中,必然产生联系的类与类(对象与对象) 之间。
    尽量使用 合成/聚合的方式,而不是使用继承。

8.精华:代码示例

解析

  • 下面一段代码是为了满足 1~7 ,所写的一段代码,粘贴运行即可
  • 代码描述的是,各种木材 、各种 厂商、生产不同家具
  • 要求:尽量满足 解耦与可扩展,并描述代码所体现的思想
  • 代码满足条件解析

  • 1.单一职责:其中,制造接口与刷漆接口已经分离。因为生产椅子需要刷漆,生产桌子不需要刷漆。

  • 2.接口隔离:其中,制造方法与刷漆方法,抽象到了两个接口中,实现接口最小化,满足隔离条件。

  • 3.依赖倒置:已经满足,面向接口编程,且如果需要扩展,只需要创建一个生产厂商类即可,不会变动旧代码。

  • 4.里氏替换:使用的是接口,而不是继承木材类,降低继承带来的耦合增强。

  • 5.开闭原则:新增生产厂商生产家具,只需要创建一个生产厂商类即可,不会变动旧代码,满足对扩展开放,对修改关闭。

  • 6.迪米特原则:其中,木材类是通过参数传递,而不是内部new出来,满足 好朋友原则。

  • 7.合成复用:木材类对象作为成员变量,通过构造函数参数传递,而不是使用继承木材类后实现,满足合成复用

//控制台输出内容:

//当前木材:杨树
//使用 杨树 制造了一张桌子
//当前木材:松树
//使用 松树 制造了一把椅子
//椅子材料 松树 ,状态:刷漆完成

interface 制造接口 {
    void 制造();
}

interface 刷漆接口 {
    void 刷漆();
}

class 木材类 {
    public String name;

    public 木材类(String name) {
        this.name = name;
        System.out.println("当前木材:" + name);
    }
}

class 桌子厂商 implements 制造接口 {
    木材类 mc;

    public 桌子厂商(木材类 mc) {
        this.mc = mc;
    }

    @Override
    public void 制造() {
        System.out.println("使用 " + mc.name + " 制造了一张桌子");
        System.out.println();

    }
}

class 椅子厂商 implements 制造接口, 刷漆接口 {
    木材类 mc;

    public 椅子厂商(木材类 mc) {
        this.mc = mc;
    }

    @Override
    public void 制造() {
        System.out.println("使用 " + mc.name + " 制造了一把椅子");
        this.刷漆();
    }

    @Override
    public void 刷漆() {
        System.out.println("椅子材料 " + mc.name + " ,状态:刷漆完成");
        System.out.println();
    }

}

//... 猫窝厂商
//... 柜子厂商
//... 木板床厂商

public class 测试类 {

    public static void main(String[] args) {

        //桌子厂商-制造桌子
        木材类 ys = new 木材类("杨树");
        桌子厂商 zz = new 桌子厂商(ys);
        zz.制造();

        //椅子厂商-制造椅子
        木材类 ss = new 木材类("松树");
        椅子厂商 yz = new 椅子厂商(ss);
        yz.制造();

        //...  猫窝厂商 制造 纯木猫窝
        //... 柜子厂商  制造 柜子
        //... 木板床厂商  制造 木板床

    }

}

《上一篇:Java-UML类图》

《下一篇:唯一的路就是正确的路 (单例模式)》

《目录:Java基础》

《幕》

  • 留白----《老吉》
  • ~ 今 ~ ? ~ ?????????? ?????????? ???????

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 21:36:26  更:2022-03-13 21:40:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:47:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码