Java中的7大设计原则

在面向对象的设计过程中,首先需要考虑的是如何同时提高一个软件系统的可维护性和可复用性。这时,遵从面向对象的设计原则,可以在进行设计方案时减少错误设计的产生,从不同的角度提升一个软件结构的设计水平。

1、单一职责

一个类尽可能只干一件事情。普通会员、vip会员、黄金会员三个类,各干自己的事。

优点:低耦合、高内聚。

2、开闭原则

对扩展开放,对修改关闭。(继承或多态)

不建议对原来的代码进行修改,可以扩展一个新的类,来实现功能。

对程序进行抽象化设计,设计出抽象类/接口,根据不同的功能来扩展子类。

class CarDemo{public static void main(String[] args) {new CarFactory().carfactory(new Aodi());new CarFactory().carfactory(new DaZhong());}
}class CarFactory{void carfactory(Car car){car.createCar();}
}abstract  class Car{public abstract void createCar();
}class Aodi extends Car{@Overridepublic void createCar() {System.out.println("造奥迪汽车");}
}class DaZhong extends Car{@Overridepublic void createCar() {System.out.println("造大众汽车");}
}

3、里氏替换原则

使用父类的地方,都可以替换成子类,程序不会产生任何错误和异常。

子类继承父类后,子类对父类方法进行重写时,需要注意:本来是要用父类中的方法,但是 子类重新修改了功能,可能会导致结果不正确。尽量不要重写父类的方法,可以新增扩展其他的功能。

package com.ffyc.javapro.ooptenet.tenet3;
public class CalculatorDemo{public static void main(String[] args) {System.out.println(new SuperCalculator().sum(5,5,5));}
}
//计算器
class Calculator {//加法public int add(int a,int b){return a+b;}//减法public int sub(int a,int b){return a-b;}
}
//超级计算器子类
class SuperCalculator extends Calculator{//重写了父类加法@Overridepublic int add(int a, int b) {return a+b+5;}//求和方法 子类新增的功能public int sum(int a,int b,int c){//调用add(),但是子类重写了父类方法,此处调用的子类方法发生了变化int result = this.add(a,b);return result+c;}
}

4、依赖倒置

如果有多个同类型时,需要抽取抽象层(抽象类、接口)。上层定义为抽象或接口,底层实现抽象或接口,进行扩展功能。

//反例
public class WorkerDemo{public static void main(String[] args) {new Worker().getMessage(new DingDing());new Worker().getMessage(new WeChat());}
}class Worker {public void getMessage(DingDing ding){System.out.println(ding.sendMessage());}public void getMessage(WeChat weChat){System.out.println(weChat.sendMessage());}
}class DingDing{public String sendMessage(){return "钉钉消息";}
}class WeChat{public String sendMessage(){return "微信消息";}
}
//正例
public class WorkerDemo{public static void main(String[] args) {new Worker().getMessage(new WeChat());}
}class Worker {public void getMessage(Message message){System.out.println(message.sendMessage());}
}interface Message{public String sendMessage();
}class WeChat implements Message{@Overridepublic String sendMessage() {return "微信消息";}
}
class DingDing implements Message{@Overridepublic String sendMessage() {return "钉钉消息";}
}

5、接口隔离

接口功能设计时,尽量减少一个接口中有过多的功能(方法),可以细分为多个接口。不要把所有的功能定义到同一个接口中,不然要实现接口中的所有方法。

6、迪米特原则

也叫最少了解原则,在一个类中,尽量不要直接使用与此类无关的类;只与最好的朋友交谈,不与默认人说话。

反例:

public class Demeter {public static void main(String[] args) {new SchoolManger().printAllEmployee(new CollegeManger());}
}
//学校员工类
class SchoolEmployee{private String id;public void setId(String id){this.id = id;}public String getId(){return id;}
}
//学院员工类
class CollegeEmployee{private String id;public void setId(String id){this.id = id;}public String getId(){return id;}
}//学院员工管理管理类
class CollegeManger{//生成学员所有的员工public List<CollegeEmployee> getCollegeEmployee(){ArrayList<CollegeEmployee> collegeEmployeeArrayList = new ArrayList();for (int i = 0; i <10 ; i++) {CollegeEmployee collegeEmployee = new CollegeEmployee();collegeEmployee.setId("学院员工的id="+i); //添加学院员工collegeEmployeeArrayList.add(collegeEmployee);}return collegeEmployeeArrayList;}}
//学校员工管理类
class SchoolManger {//生成学校的员工public List<SchoolEmployee> getSchoolEmployee() {ArrayList<SchoolEmployee> employeeArrayList = new ArrayList();for (int i = 0; i < 5; i++) {SchoolEmployee employee = new SchoolEmployee();employee.setId("学校的员工id=" + i);employeeArrayList.add(employee);}return employeeArrayList;}//输出学校员工和学院员工信息public void printAllEmployee(CollegeManger collegeManger) {//获取到学校员工List<SchoolEmployee> employeeArrayList = this.getSchoolEmployee();System.out.println("--------学校员工--------");for (SchoolEmployee employee1 : employeeArrayList) {System.out.println(employee1.getId());}System.out.println("--------学院员工--------");List<CollegeEmployee> collegeEmployees = collegeManger.getCollegeEmployee();//SchoolManger中出现CollegeEmployee,此类与SchoolManger并非直接朋友,不合理for (CollegeEmployee collegeEmployee : collegeEmployees) {System.out.println(collegeEmployee.getId());}}
}

正例:

public class Demeter {public static void main(String[] args) {new SchoolManger().printAllEmployee(new CollegeManger());}
}
//学校员工类
class SchoolEmployee{private String id;public void setId(String id){this.id = id;}public String getId(){return id;}
}
//学院员工类
class CollegeEmployee{private String id;public void setId(String id){this.id = id;}public String getId(){return id;}
}//学院员工管理管理类
class CollegeManger{//生成学院所有的员工public List<CollegeEmployee> getCollegeEmployee(){ArrayList<CollegeEmployee> collegeEmployeeArrayList = new ArrayList();for (int i = 0; i <10 ; i++) {CollegeEmployee collegeEmployee = new CollegeEmployee();collegeEmployee.setId("学院员工的id="+i); //添加学院员工collegeEmployeeArrayList.add(collegeEmployee);}return collegeEmployeeArrayList;}public void printCollegeEmployee(){List<CollegeEmployee> collegeEmployee = getCollegeEmployee();for (CollegeEmployee employee : collegeEmployee) {System.out.println("学员员工id="+employee.getId());}}
}
//学校员工管理类
class SchoolManger {//生成学校的员工public List<SchoolEmployee> getSchoolEmployee() {ArrayList<SchoolEmployee> employeeArrayList = new ArrayList();for (int i = 0; i < 5; i++) {SchoolEmployee employee = new SchoolEmployee();employee.setId("学校的员工id=" + i);employeeArrayList.add(employee);}return employeeArrayList;}//输出学校员工和学院员工信息public void printAllEmployee(CollegeManger collegeManger) {//获取到学校员工List<SchoolEmployee> employeeArrayList = this.getSchoolEmployee();System.out.println("--------学校员工--------");for (SchoolEmployee employee1 : employeeArrayList) {System.out.println(employee1.getId());}//CollegeManger与SchoolManger是直接朋友,相互之间访问System.out.println("--------学院员工-----------");collegeManger.printCollegeEmployee();}
}

7、组合/聚合复用原则

如果想在一个类中达到复用别的类中的方法,优先使用关联/依赖,其次才考虑继承。

案例:现在假设有一个A类,里面有两个方法,B类想要复用这两个方法,请问有几种方案?

public class A {public void method01(){}public void method02(){}
}class B{A a;//关联关系。A作为B类的成员变量,尽量避免使用继承public void setA(A a){this.a = a;}public void use(){a.method01();a.method02();}
}class Test{public static void main(String[] args) {A a = new A();B b = new B();b.setA(a);b.use();}
}
public class A {public void method01(){}public void method02(){}
}class B{public void use(A a){//将A作为参数使用,依赖关系a.method01();a.method02();}
}class Test{public static void main(String[] args) {A a = new A();B b = new B();b.use(a);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/190197.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用于强化学习的置换不变神经网络

一、介绍 如果强化学习代理提供的输入在训练中未明确定义&#xff0c;则通常表现不佳。一种新方法使 RL 代理能够正常运行&#xff0c;即使受到损坏、不完整或混乱的输入的影响也是如此。 “大脑能够使用来自皮肤的信息&#xff0c;就好像它来自眼睛一样。我们不是用眼睛看&…

重磅发布 OpenAI 推出用户自定义版 ChatGPT

文章目录 重磅发布 OpenAI 推出用户自定义版 ChatGPT个人简介 重磅发布 OpenAI 推出用户自定义版 ChatGPT OpenAI 首届开发者大会 (OpenAI DevDay) 于北京时间 11 月 7 日凌晨 02:00 开始&#xff0c;大会上宣布了一系列平台更新。其中一个重要更新是用户可以创建他们自己的自定…

Spring Cloud学习(七)【Docker 容器】

文章目录 初识 DockerDocker 介绍Docker与虚拟机Docker架构安装 Docker Docker 基本操作镜像相关命令容器相关命令数据卷 Dockerfile 自定义镜像镜像结构Dockerfile DockerComposeDockerCompose介绍安装DockerCompose Docker镜像仓库常见镜像仓库服务私有镜像仓库 初识 Docker …

里氏代换原则

package com.jmj.principles.dmeo2.after;/*** 四边形接口*/ public interface Quadrilateral {double getLength();double getWidth();}package com.jmj.principles.dmeo2.after;/*** 长方形类*/ public class Rectangle implements Quadrilateral{private double length;priv…

WPF ToggleButton 主题切换动画按钮

WPF ToggleButton 主题切换动画按钮 仿造最近看到的html中的一个效果&#xff0c;大致思路是文章这样&#xff0c;感觉还可以再雕琢一下。 代码如下 XAML: <UserControl x:Class"WPFSwitch.AnimationSwitch"xmlns"http://schemas.microsoft.com/winfx/200…

取暖器/暖风机上架 亚马逊美国站UL1278测试标准要求

美国是一个对安全要求非常严格的国家&#xff0c;美国本土的所有电子产品生产企业早在很多年前就要求有相关检测。而随着亚马逊在全球商业的战略地位不断提高&#xff0c;境外的电子设备通过亚马逊不断涌入美国市场。“为保证消费者得安全&#xff0c;亚马逊始终强调带电得产品…

用python将csv表格数据做成热力图

python的开发者为处理表格和画图提供了库的支持&#xff0c;使用pandas库可以轻松完成对csv文件的读写操作&#xff0c;使用matplotlib库提供了画热力图的各种方法。实现这个功能首先需要读出csv数&#xff0c;然后设置自定义色条的各种属性如颜色&#xff0c;位置&#xff0c;…

Java进阶(垃圾回收GC)——理论篇:JVM内存模型 垃圾回收定位清除算法 JVM中的垃圾回收器

前言 JVM作为Java进阶的知识&#xff0c;是需要Java程序员不断深度和理解的。 本篇博客介绍JVM的内存模型&#xff0c;对比了1.7和1.8的内存模型的变化&#xff1b;介绍了垃圾回收的语言发展&#xff1b;阐述了定位垃圾的方法&#xff0c;引用计数法和可达性分析发以及垃圾清…

2012年7月11日 Go生态洞察:Gccgo在GCC 4.7.1中的集成

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

2023亚太杯数学建模A题B题C题思路代码分析

文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料5 最后 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 2023年第十三…

github私有仓库开发,公开仓库发布版本

文章目录 github私有仓库开发,公开仓库发布版本需求背景实现思路GitHub Releases具体步骤广告 github私有仓库开发,公开仓库发布版本 需求背景 github私有仓库开发,公开仓库发布版本&#xff0c;既可以保护源代码,又可以发布版本给用户使用。许多知名软件项目都采用了这样的开…

仓库管理系统(WMS)升级解决方案—条码引入

在企业的整个供应链中&#xff0c;仓储起着至关重要的作用&#xff0c;如果不能保证正确的进货和库存控制及发货&#xff0c;将会导致管理费用的增加&#xff0c;服务质量难以得到保证&#xff0c;从而影响企业的竞争力。 传统简单、静态的仓库管理通常以结果为导向&#xff0…

高效批量剪辑、处理和添加水印,用视频批量剪辑高手轻松搞定!

您是否曾经在处理大量视频时&#xff0c;因为剪辑、处理和添加水印等问题而感到烦恼&#xff1f;是否因为这些问题而大大降低了您的工作效率&#xff1f;现在&#xff0c;我们为您推荐一款全新的视频批量剪辑工具——视频批量剪辑高手&#xff0c;让您的工作效率瞬间翻倍&#…

新型的铁塔基站“能源管家”

安科瑞 崔丽洁 引言&#xff1a;随着5G基站的迅猛发展&#xff0c;基站的能耗问题也越来越突出&#xff0c;高效可靠的基站配电系统方案&#xff0c;是提高基站能耗使用效率&#xff0c;实现基站节能降耗的重要保证&#xff0c;通过多回路仪表监测每个配电回路的用电负载情况&a…

MySQL索引优化

EXPLAIN详解 优先了解EXPLAIN&#xff0c;文章链接在下面。 EXPLAIN详解&#xff08;MySQL&#xff09; 索引数据结构 MySQL主要有两种结构&#xff1a;hash索引和BTree索引&#xff0c;InnoDB引擎默认是BTree索引。 索引分类 聚簇索引&#xff1a; 指索引的键值的逻辑顺…

基于若依的ruoyi-nbcio流程管理系统增加读取节点扩展属性的方法

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 我们的在流程设计器里会根据需要再不同的节点增加扩展属性&#xff0c;如何动态读取这些扩展属性&#xff…

Python:Unittest框架快速入门:用例、断言、夹具、套件、HTML报告、ddt数据驱动

快速看了套Unittest的入门教程 软件测试全套资料赠送_哔哩哔哩_bilibili软件测试全套资料赠送是快速入门unittest测试框架&#xff01;全实战详细教学&#xff0c;仅此一套&#xff01;的第1集视频&#xff0c;该合集共计11集&#xff0c;视频收藏或关注UP主&#xff0c;及时了…

matlab GUI界面实现ZieglerNicholas调节PID参数

1、内容简介 略 11-可以交流、咨询、答疑 ZieglerNicholas、PID、GUI 2、内容说明 GUI界面实现ZieglerNicholas调节PID参数 通过ZieglerNicholas调节PID参数&#xff0c;设计了GUI 3、仿真分析 略 4、参考论文 略 链接&#xff1a;https://pan.baidu.com/s/1yQ1yDfk-_…

单片机定时器讲解和实现

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、计数器是什么&#xff1f;二、单片机定时器结构2.1***两个8位如何合成16位&#xff0c;16位如何分成两个8位***2.2 计数器的位数组合&#xff1f;2.3 定时功…