面向对象的设计模式

news2025/1/15 12:59:50

"万丈高楼平地起,7种模式打地基",模式是一种规范,我们应该站在巨人的肩膀上越看越远,接下来,让我们去仔细了解了解面向对象的7种设计模式

7种设计模式

设计原则的核心思想

  • 找出应用中可能需要变化之处,独立出来,不要和不需要变化的代码混在一起

  • 针对接口编程,而坏是针对实现编程

  • 为了交互对象的耦合性而设计

  • 为了使程序高内聚,低耦合

  • 单一职责低耦合,高内聚

每一个类负责的任务很明确,降低代码之间的耦合度,如果代码耦合度较高,动一点则要动全身,当变化发生时设计或遭受到意想不到的破坏

public class Run {
  
     public  void run(){
          System.out.println("跑步");
     }
}

在Run类中只负责了Run()的功能,不负责其他的功能,在设计改变类的时候对整体的影响不大

  • 开闭原则适应性和灵活性 稳定性和延续性 可复用性和可维护性

在软件开发的过程中,随着版本的更替,软件的需求会越来越多,如果是修改的内容的话,会很费时,但是我们换个思路,如果在设计模式的时候,我们可以先评估出最容易发生的类,然后对其进行抽象化设计,当变化发生时,只需要增加新的具体类来实现新的业务功能

未使用开/闭原则:

/*
  开闭原则引入案例
 */
public class CarDemo {

    public static void main(String[] args) {
        new CarFactory().createCar(1);
        new CarFactory().createCar(2);
        new CarFactory().createCar(3);
     //后期如果需要添加车型,CarFactory需要修改代码
        //new CarFactory().createCar(4);
        //new CarFactory().createCar(5);
    }

}

/*
   汽车工程类,专门负责造汽车
 */
class CarFactory{

    /*
       违反了开闭原则,后期如果添加新的汽车类,则需要修改代码
     */
    public void createCar(int type){
          if(type==1){
              System.out.println("造宝马汽车"+new Car("宝马汽车"));
          }else if(type==2){
              System.out.println("造奥迪汽车"+new Car("奥迪汽车"));
          }else{
              System.out.println("造大众汽车"+new Car("大众汽车"));
          }
    }

}

/*
Car类
*/
class Car{
    String name;//定义了一个成员变量

    public Car(String name) {//有参构造函数
        this.name = name;
    }
}

使用开/闭原则:

/*
开闭原则案例
 */
class CarDemo{

    public static void main(String[] args) {
           new CarFactory().carfactory(new BMW());
           new CarFactory().carfactory(new Aodi());
           new CarFactory().carfactory(new DaZhong());

    }

}

//创建一个CarFactory类
class CarFactory{
         //创建一个车辆工厂的方法

      void   carfactory(Car car){
          car.createCar();
      }
}

   //创建一个抽象类Car
abstract  class Car{
   //创建一个创建车辆的抽象方法
   public abstract   void createCar();
}

/*
如果想添加车辆型号的话,只需要创建一个类继承Car类并实现createCar()方法,不用修改代码
*/

//继承并重写Car里的方法
class BMW extends Car{

    @Override
    public void createCar() {
        System.out.println("造宝马汽车");
    }
}

//继承并重写Car里的方法
class Aodi extends Car{
    @Override
    public void createCar() {
        System.out.println("造奥迪汽车");
    }
}

//继承并重写Car里的方法
class DaZhong extends Car{
    @Override
    public void createCar() {
        System.out.println("造大众汽车");
    }
}

//继承并重写Car里的方法
class BC extends Car{
    @Override
    public void createCar() {
        System.out.println("造奔驰汽车");

        Calendar.getInstance();
        new GregorianCalendar();
    }
}
  • 里氏替换原则(提高代码的复用性、提高代码的可扩展性 | 继承是具有侵入性的 增大了耦合性 )

基本概念继承必须确保超类锁拥有的性质在子类中仍然成立(子类继承父类后,尽量不要重写父类的方法,可以新增扩展其他的功能.保证子类功能的正确性. 不能让功能修改后,导致程序出错)

主要作用

  1. 里氏替换原则是实现开闭原则的重要方式之一

  1. 克服了继承中重写父类方法造成的可复用性变差的缺点

  1. 功能正确的保证

  1. 加强了程序的健壮性,提高了程序的维护性降低需求变更时引入的风险

代码演练:

/*
  里氏替换原则演示案例
  计算器父类
*/

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;
        }
}

没有重写父类方法时,输出还是正确结果15,但是重写之后却改变了值,输出了错误的结果20

  • 依赖倒置(都依赖于抽象)

让程序面向抽象类编程、面向接口编程(依赖于抽象接口,对抽象进行编程)

/*
  依赖倒置引入案例
 */
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();
}

//添加一个信息需要创建一个类实现Message接口
class WeChat implements Message{
    @Override
    public String sendMessage() {
        return "微信消息";
    }
}
class DingDing implements Message{

    @Override
    public String sendMessage() {
        return "钉钉消息";
    }
}
  • 接口隔离

使用多个接口,不使用单一的总接口(这个最好理解,在这里就不解释了)

  • 迪米特原则

一个对象应该对其他对象有最少的了解(在一个类中,应尽量少的使用与其没有直接关系的类)

直接关系

  1. 类中的成员属性

  1. 在类中的方法作为参数使用

  1. 在类中的方法作为返回值类型

注意事项

  1. 核心是降低类之间的耦合

  1. 从被依赖折者的角度来看,尽量将逻辑封装在类的内部,对外除了提供的public方法,不泄露任何信息

  1. 从依赖者的角度来说,只依赖应该依赖的对象

  1. 切记不要为了用而用

代码实现:

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();
        //此处学校管理类中出现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();
    }
}
  • 组合/聚合复用原则(优先使用组合,使系统更灵活,其次才考虑继承,达到复用的目的)

代码实现:

/*
   组合/聚合复用原则案例1  使用依赖实现复用
 */
public class A {

    public void method01() {
    }

    public void method02() {
    }
}


class B extends A {
    private A a;

    public void method() {
    }
}

class Test {
    public static void main(String[] args) {
        new B().method01();
        new B().method02();
    }
}
/*
   组合/聚合复用原则案例2  使用组合/聚合实现复用
 */
public class A {

      public void method01(){
      }

      public void method02(){
      }
}


class B{

     A a;

     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();
    }
}
/*
   组合/聚合复用原则案例3  使用依赖实现复用
 */
public class A {

      public void method01(){
      }

      public void method02(){
      }
}


class B{
     public void use(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/335778.html

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

相关文章

24考研|高等数学的基础概念定理(二)——第二章|导数与微分

文章目录一、基础概念定理部分1.1 导数的四则运算法则1.2 反函数的求导法则1.3 复合函数的求导法则1.4 费马引理1.5 罗尔定理1.6 拉格朗日中值定理1.7 导数为零的结论1.8 柯西中值定理1.9 洛必达法则1.10 泰勒中值定理&#xff08;定理1&#xff0c;定理2&#xff09;1.11 导数…

CRM系统能给企业带来什么? CRM系统推荐

什么是CRM系统&#xff1f; CRM系统&#xff08;又称客户关系管理系统&#xff09;是一个以客户为核心的管理软件&#xff0c;能有效改善企业与现有客户的关系&#xff0c;且帮助企业寻找新的潜在客户&#xff0c;并赢回以前老客户。 CRM系统能给企业带来什么&#xff1f; C…

计算机视觉框架OpenMMLab开源学习(五):目标检测实战

目标检测实战 前言&#xff1a;本篇主要偏向目标检测实战部分&#xff0c;使用MMDetection工具进行代码应用&#xff0c;最后对水果进行检测实战演示&#xff0c;本次环境和代码配置部分省略&#xff0c;具体内容建议参考前一篇文章&#xff1a;计算机视觉框架OpenMMLab开源学…

基于STM32设计的避障寻迹小车

一、前言 1.1 项目背景 根据美国玩具协会在一项研究中&#xff0c;过去几年全球玩具销售增长与GDP的世界平均水平大致相同。但全球玩具市场的内部结构已经占据了巨大的位置变化&#xff1a;传统玩具的市场份额正在下降&#xff0c;高科技电子玩具正在蓬勃发展。全球玩具市场的…

迁移至其他美国主机商时需要考虑的因素

网站的可访问性是关系业务的关键因素之一。一个稳定、快速且优化良好的主机上的网站更有可能享受不间断的流量&#xff0c;并在谷歌的SERP中获得更好的排名。因此&#xff0c;在构建企业网站时&#xff0c;选择合适的主机商相当重要。不过就以美国主机为例&#xff0c;由于每个…

three.js学习笔记(一):THREE.Materail五种基础材质的使用

MeshBasicMaterial&#xff08;网格基础材质&#xff09;&#xff1a;基础材质&#xff0c;用于给几何体赋予一种简单的颜色&#xff0c;或者显示几何体的线框。MeshDepthMaterial&#xff08;网格深度材质&#xff09;&#xff1a; 这个材质使用从摄像机到网格的距离来决定如何…

企业舆情监测多少钱,TOOM舆情监测专业服务平台

企业舆情监测的费用因公司不同而异&#xff0c;具体需要多少钱取决于您的需求和舆情监测公司的收费标准。一些因素&#xff0c;如舆情监测范围、数据收集方式、舆情分析报告等细节&#xff0c;都可能影响最终的费用。最好联系舆情监测公司询问具体收费标准。企业舆情监测多少钱…

Linux_用户和权限

一、认识root用户 --超级管理员 root用户拥有最大的系统操作权限&#xff0c;而普通用户在许多地方都是受限的 普通用户的权限&#xff0c;一般在其home目录内是不受限的 一旦出了home目录&#xff0c;大多数地方普通用户仅有只读和执行权限&#xff0c;无修改权限 1、su和…

linux配置密码过期的安全策略(/etc/login.defs的解读)

长期不更换密码很容易导致密码被破解&#xff0c;而linux的密码过期安全策略主要在/etc/login.defs中配置。一、/etc/login.defs文件的参数解读1、/etc/login.defs文件的内容示例[rootlocalhost ~]# cat /etc/login.defs # # Please note that the parameters in this configur…

10.jQuery中请求预处理 $.ajaxPrefilter()

在使用jQuery发起请求的时候($.get(),$.post().$ajax()都可以)会默认在请求前调用$.ajaxPrefilter()这个函数&#xff0c;我们可以利用这个来做一些事情 目录 1 定义API根路径 2 添加请求头 3 添加请求结束的回调函数 1 定义API根路径 这样后面每次请求就不用再写根路…

什么样的帮助文档才能帮助用户?

尼尔森十大交互原则的最后一个原则——“人性化帮助原则”提出&#xff0c;我们应该给系统提供一份帮助文档&#xff0c;让用户能够尽快了解系统&#xff0c;熟悉操作。 互联网时代&#xff0c;很多软件都把用户习惯培养起来了&#xff0c;对于大部分软件都有一种无师自通的感…

MySQL安装配置(Windows和 Linux )

MySQL安装配置&#xff08;Windows和 Linux &#xff09; 文章目录MySQL安装配置&#xff08;Windows和 Linux &#xff09;一、MySQL 下载1. 1 点击 **DOWNLOADS**1.2 点击 **MySQL Community (GPL) Downloads **1.3 点击 **MySQL Community Server**1.4 此时跳转到最新版本的…

2023年Q1业绩增长背后,迪士尼亟待扭转流媒体亏损困局

重新执掌迪士尼后&#xff0c;鲍勃伊格尔交出了一份表现尚可的“答卷”。 图源:迪士尼 美东时间2023年2月8日&#xff0c;迪士尼披露了2023财年Q1财报&#xff0c;营收为235.1亿美元&#xff0c;同比增长8%&#xff1b;持续经营净利润13亿美元&#xff0c;同比增长11%。受此利…

红米9a手动root方法

简介 已知红米6A/6/9/9A/9C/10A机器都可以快速解锁BL&#xff0c;无任何变砖风险 并且秒解锁BL后和官方解锁一样&#xff0c;无任何其他不良影响。推荐大家使用官网解锁&#xff0c;需要等待7天。 ​ BootLoader BootLoader是在操作系统内核运行之前运行的一段小程序。其实…

【虚拟仿真】Unity3D实现从浏览器拉起本地exe程序并传参数

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 最近有项目需求&#xff0c;从浏览器调起来本地的exe程序&…

常见HTTP请求错误码大全

响应码由三位十进制数字组成&#xff0c;它们出现在由HTTP服务器发送的响应的第一行。 响应码分五种类型&#xff0c;由它们的第一位数字表示&#xff1a; 1xx&#xff1a;信息&#xff0c;请求收到&#xff0c;继续处理 2xx&#xff1a;成功&#xff0c;行为被成功地接受、…

【Nacos】Nacos配置中心服务端源码分析

上文说了Nacos配置中心客户端的源码流程&#xff0c;这篇介绍下Nacos配置中心服务端的源码。 服务端的启动 先来看服务启动时干了啥&#xff1f; init()方法上面有PostConstruct&#xff0c;该方法会在ExternalDumpService实例化后执行。 com.alibaba.nacos.config.server.s…

第三方电容笔怎么样?开学适合买的电容笔

随着科学技术的进步&#xff0c;很多新型的电子产品和数码设备都出现了。比如手机&#xff0c;IPAD&#xff0c;蓝牙耳机&#xff0c;电容笔等等。实际上&#xff0c;如果你想要更好的使用ipad&#xff0c;那么你就需要一支电容笔。比如ipad&#xff0c;我们用ipad来做笔记&…

面向战场的cesium基础到进阶的案例展示(我相信VIP总是有原因的)

cesium 前置说明(友情提示,关注重点代码,其他影响复现的都可以删除或者替换数值解决) 这里面用到了cesium的模型加载、图片加载、着色器、实时改变模型状态、模型删除等知识点,这需要你自己去观摩下述会包含所有相关代码,他们的联系其实在代码中能看到(比如飞机操作类会…

告别传统繁杂的采购合同管理 打造企业自动化采购管理模式

随着企业竞争日趋激烈&#xff0c;采购成本压力剧增&#xff0c;企业对于采购合同管理更加严格&#xff0c;从而把控物资成本。对于任何一家企业采购来说&#xff0c;规范化合同的全面管理&#xff0c;是采购活动中重要的一个环节。 但在如今&#xff0c;依旧有很多企业采购合…