Java中的7大设计原则

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

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{
    @Override
    public void createCar() {
        System.out.println("造奥迪汽车");
    }
}

class DaZhong extends Car{
    @Override
    public 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{
    //重写了父类加法
    @Override
    public 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{
    @Override
    public String sendMessage() {
        return "微信消息";
    }
}
class DingDing implements Message{
    @Override
    public 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.coloradmin.cn/o/1200441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

js案例:打地鼠游戏(打灰太狼)

效果预览图 游戏规则 当灰太狼出现的时候鼠标左键点击灰太狼加10分&#xff0c;小灰灰出现的时候鼠标左键点小灰灰击减10分&#xff0c;不点击不减分不加分。 整体思路 1.把获取背景图片中每个地洞的位置&#xff0c;把所有位置放到一个数组中。 2.封装随机数函数&#xff0c;随…

基于飞蛾扑火算法优化概率神经网络PNN的分类预测 - 附代码

基于飞蛾扑火算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于飞蛾扑火算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于飞蛾扑火优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

【每日逆向】BUUCTF--[ACTF新生赛2020] easyre

拿到exe文件先查下信息&#xff0c;是一个32位程序&#xff0c;加了壳。 不会脱&#xff0c;直接拿到自动脱壳机潦草结束 看着有点乱&#xff0c;稍微改改 嗯&#xff0c;这样舒服多了。就是将V6扩展到18个字节大小&#xff0c;V5也扩展到12个字节大小&#xff0c;这样更符合源…

从0开始python学习-33.夹具@pytest.fixture(scope=““,params=““,autouse=““,ids=““,name=““)

目录 1. 创建夹具 1.1 pytest方式 1.2 unittest方式 2. 使用夹具 2.1 通过参数引用 2.2 通过函数引用 3. 参数详解 3.1 scope&#xff1a;作用域 3.2 params-参数化 3.3 autouseTrue表示自动使用&#xff0c;默认为False 3.4 ids&#xff1a;设置变量名 3.5 name&am…

基于斑点鬣狗算法优化概率神经网络PNN的分类预测 - 附代码

基于斑点鬣狗算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于斑点鬣狗算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于斑点鬣狗优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

推荐系统笔记--基于物品的协同过滤(Item CF)

1--基本原理 Item CF的原理是根据物品的相似度来将新的物品推荐给用户&#xff1b;下图中用户对红色物品的感兴趣度为 [2, 1, 4, 3]&#xff0c;红色物品与橙色物品的相似度为 [0.1, 0.4, 0.2, 0.6]&#xff0c;因此可以计算出用户对橙色物品的感兴趣度。 Item CF的基本思想是&…

江西开放大学引领学习新时代:电大搜题助力学子迈向成功

江西开放大学&#xff08;简称江西电大&#xff09;一直以来致力于为学子提供灵活便捷的学习服务。近年来&#xff0c;携手电大搜题微信公众号&#xff0c;江西开放大学以其卓越的教学质量和创新的教学手段&#xff0c;为广大学子开启了一扇通向成功的大门。 作为一家知名的远…

LiteVNA 能做什么?

最近入手了一台 LiteVNA 设备&#xff0c;性价比非常高。因为之前没有接触过 VNA 这种测试仪器&#xff0c;所以准备好好研究一下。和它类似的一个项目是 NanoVNA6000&#xff0c;价格要高些&#xff0c;但可能性能要好点&#xff0c;另外&#xff0c;文档也要全一些。 VNA …

上机4KNN实验4

目录 编程实现 kNN 算法。一、步骤二、实现代码三、总结知识1、切片2、iloc方法3、归一化4、MinMaxScale&#xff08;&#xff09;5、划分测试集、训练集6、KNN算法 .py 编程实现 kNN 算法。 1、读取excel表格存放的Iris数据集。该数据集有5列&#xff0c;其中前4列是条件属性…

【C++破局】泛型编程|函数模板|类模板

​作者主页 &#x1f4da;lovewold少个r博客主页 ⚠️本文重点&#xff1a;c模板初阶知识点讲解 &#x1f449;【C-C入门系列专栏】&#xff1a;博客文章专栏传送门 &#x1f604;每日一言&#xff1a;花有重开日&#xff0c;人无再少年 目录 前言 泛型编程 函数模板 函数模…

我的一点记录 —— 256天

机缘 之所以开始坚持写博客&#xff0c;是希望可以借此对所学的知识进行一个巩固&#xff0c;并方便日后的复习。在CSDN这个平台&#xff0c;我也确实学到了很多有质量的内容&#xff0c;同时也希望自己可以向外输出高质量且有水平的相关知识。256天&#xff0c;蛮快的&#x…

基于被囊群算法优化概率神经网络PNN的分类预测 - 附代码

基于被囊群算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于被囊群算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于被囊群优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络…

advanced-css: No.1

本套教程学习来自视频&#xff1a;https://www.bilibili.com/video/BV1n94y1o7yS/?p7&spm_id_frompageDriver&vd_sourceb79be8283df9418cb45941cc0bd583c6 案例 实现效果图 代码 HTML: <!DOCTYPE html> <html lang"en"><head><meta c…

【Unity之UI编程】玩法面板的实现

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;UI_…

Nacos热更新

Nacos热更新 相比其他注册中心&#xff0c;Nacos的优势之一在于热更新。 热更新&#xff0c;就是不需要重启服务&#xff0c;就能够更新配置。 nacos配置中心 首先&#xff0c;需要搭建 Nacos&#xff0c;详情见&#xff1a; https://www.cnblogs.com/expiator/p/17392549.h…

深度解剖Linux权限的概念

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;牢记Linux权限的概念。 > 毒鸡汤&#xff1a;你…

k8s笔记资源限制,亲和和性 污点和容忍

镜像下载失败 当宿主机资源不足时&#xff0c;会把pod kill &#xff0c;在其他node 重建 在宿主机放可能多的资源 requests(请求) limits(限制) 超出百分比 容器 pod namespace级别 pod使用资源过多&#xff0c;导致宿主机资源不足&#xff0c;会导致重建pod cpu 内存限…

通过Malloc 和 Free 的具体实现 加深对C指针 的理解(笔记)

【彻底搞懂C指针】Malloc 和 Free 的具体实现 https://danluu.com/malloc-tutorial/ 进程间的通信 : ①共享内存 ② 消息传递 &#xff08;内核实现&#xff09; 分配策略 (实现方面) by DUCK sbrk() malocal实现的主要函数 man sbrk 查看 数据结构 一个参考代码 https…

2.如何实现API统一响应-web组件篇

文章目录 1. 统一响应1.1 CommonResult 1. 统一响应 前端调用api接口获得统一的响应&#xff1a; 成功&#xff0c;返回成功的状态码和数据&#xff1b;失败&#xff0c;返回失败的状态码和错误提示。 在标准的 RESTful API 的定义&#xff0c;是推荐使用 HTTP 响应状态码 (…

PEFT概述:最先进的参数高效微调技术

了解参数高效微调技术&#xff0c;如LoRA&#xff0c;如何利用有限的计算资源对大型语言模型进行高效适应。 PEFT概述&#xff1a;最先进的参数高效微调技术 什么是PEFT什么是LoRA用例使用PEFT训练LLMs入门PEFT配置4位量化封装基础Transformer模型保存模型加载模型推理 结论 什…