富途面试题:用面向对象的思想设计人关门的场景

news2024/11/17 7:25:09

我工作两年后,有一次不成功的富途证券的面试,印象非常深刻,面试官提出了一个看似简单实则充满深意的问题:如何用面向对象的思想设计一个人关门的场景?

在这里插入图片描述

我当时是这样设计的,创建两个类:PersonDoor

public class Person {
	private String name;
	public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public void closeDoor(Door door) {
        if (door.isOpen) {
            door.isOpen = false;
            System.out.println("门已关闭");
        } else {
            System.out.println("门已经关闭");
        }
    }
}

public class Door {
    public boolean isOpen; // 门的状态

    public Door(boolean isOpen) {
        this.isOpen = isOpen;
    }
}

我完成之后,面试官接着问了我一个问题:你觉得关门这个逻辑,是人对象实现还是门对象实现比较好?这两种设计的区别是什么?

当时我对封装的理解还不是很深入,导致设计和回答的都不理想。

一,封装

在面向对象编程中,封装是最基本的原则之一,它指的是将对象的状态(属性)和行为(方法)封装在一起,并对外界隐藏其内部实现细节的过程。

这样做有两个主要目的

  • 一是增强代码的安全性,防止外部对内部数据的不当修改
  • 二是提高模块间的解耦,使得代码更加易于理解和维护

封装的实现手段:

  • 访问控制符:通过public、private、protected等访问修饰符来控制类成员的访问级别。最佳实践是成员变量尽可能用private修饰,对外提供方法修改成员变量

  • 抽象接口:提供简洁的公共接口,隐藏实现细节,使得外部只需知道如何使用而无需关心如何实现

基于上述知识,有一个设计原则:对象代表什么,就必须封装相关的状态,并提供操作状态的方法。

二,正确的设计是怎样的呢?

1,我的设计的不足之处

代码展示

public class Door {
    public boolean isOpen; // 门的状态

    public Door(boolean isOpen) {
        this.isOpen = isOpen;
    }
}

public class Person {
    public void closeDoor(Door door) {
        if (door.isOpen) {
            door.isOpen = false;
            System.out.println("门已关闭");
        } else {
            System.out.println("门已经关闭");
        }
    }
}

此设计违背封装原则:

  • Door类的isOpen属性直接被设为public,任何外部类都可以直接访问并修改它,这不仅破坏了数据的安全性,也使得Door的状态管理变得混乱
  • Person类直接操作Door的状态,增加了类之间的耦合度

2,正确设计

代码展示

public class Door {
    private boolean isOpen; // 私有化状态

    public Door(boolean isOpen) {
        this.isOpen = isOpen;
    }

    public boolean isOpen() {
        return isOpen;
    }

    public void close() {
        if (isOpen) {
            isOpen = false;
            System.out.println("门已关闭");
        } else {
            System.out.println("门已经是关闭状态");
        }
    }
}

public class Person {
    public void attemptToCloseDoor(Door door) {
        if (door.isOpen()) {
            door.close();
        }
    }
}

在这个设计中,明显加强了封装性:

  • 门的状态现在是私有的,外部不能直接访问或修改,只能通过提供的isOpen()方法来检查门的状态
  • 关门操作被封装在Door类内部的close()方法中,确保了对门状态的更改遵循预定逻辑
  • Person类通过调用Door的公共接口(即isOpen()close()方法)来尝试关门,而不是直接操作门的状态,这减少了类间的耦合,提升了代码的可维护性和扩展性

也就是说,虽然是人关门,关门逻辑应由门对象实现,而不是人对象实现。因为是门的状态,这个状态的改变,必须由门对象完成,才符合封装的设计理念。

3,自己GG还是被GG

为了加深对上述原则的理解,举个不和谐的例子:张三把李四砍了,李四GG,那么请问,从面向对象的角度,让李四GG的方法是由张三提供还是李四提供呢?

在这里插入图片描述

显然,按照封装思想,李四被砍导致生命状态从活着变成GG,应该由李四自己提供改变生命状态的方法,张三砍人的动作就是调用李四提供的这个方法。

乍看起来有点怪异,都从面向对象的封装思想来看,就得这么设计。

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

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

相关文章

Linux命令那么多,先来一篇文件和目录管理命令!

💡本文建议大家收藏! 文件和目录管理命令 1. ls - 列出目录内容 ls命令是Linux中最常用的命令之一,用于列出目录中的文件和子目录。 ls显示当前目录下的所有文件和目录。 ls -l以长格式列出目录内容,显示文件权限、所有者、大…

云途探索——移动云云日志接入实践

目录 1 前言2 新手入门2.1 前置条件2.2. 配置采集对象及规则2.3 安装Agent2.4 日志管理 3 使用场景3.1 优势3.2 应用场景 4 总结 1 前言 随着人工智能、大数据、物联网以及云计算时代的到来,在日志数据量持续爆增、日志数据日益多样化的今天,传统日志服…

Java(六)——抽象类与接口

文章目录 抽象类和接口抽象类抽象类的概念抽象类的语法抽象类的特性抽象类的意义 接口接口的概念接口的语法接口的特性接口的使用实现多个接口接口与多态接口间的继承抽象类和接口的区别 抽象类和接口 抽象类 抽象类的概念 Java使用类实例化对象来描述现实生活中的实体&…

[数据集][图像分类]家庭场景下的家具分类数据集1010张101类别

数据集类型:图像分类用,不可用于目标检测无标注文件 数据集格式:仅仅包含jpg图片,每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数):1010 分类类别数:101 类别名称:[“bath_bath”,“bath_heated_t…

java版CRM客户关系管理系统源码-CRM客户关系管理系统的技术架构与功能实现

CRM客户关系管理系统的技术架构与功能实现 一、引言 随着市场竞争的日益激烈,客户关系管理(CRM)已成为企业赢得市场、提升客户满意度、促 进业务增长的关键手段。本文旨在介绍一款先进的CRM客户关系管理系统的技术架构与功能实现&#xff0…

C++:类的内存分布

类的成员变量和方法是分开存储的,内存给类实例化出的对象开辟空间时只开辟成员变量所占用的空间。类中的所有方法(成员函数)都会放在代码区,所以类的大小一般只计算类中成员变量的对齐之后大小的综合(如果没有虚函数的…

Java设计模式 _行为型模式_观察者模式

一、观察者模式 1、观察者模式 观察者模式 ( Observer Pattern )是一种行为型模式。 常用于对象间存在一对多关系时,比如,当一个对象被修改时,需要自动通知它的依赖对象。 2、实现思路 (1)、定义被观察者的行为&…

ETLCloud中如何执行SQL脚本

SQL脚本 在数据库管理与数据分析的广阔领域中,SQL(Structured Query Language,结构化查询语言)脚本扮演着举足轻重的角色。作为一门专为关系型数据库设计的编程语言,SQL不仅能够执行数据的检索、更新、插入及删除等基…

算法与数据结构:二叉排序树与AVL树

ACM大牛带你玩转算法与数据结构-课程资料 本笔记属于船说系列课程之一,课程链接: 哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep66799?csourceprivate_space_class_null&spm_id_from333.999.0.0 你也可以选择购买『船说系列课程-年度会…

便携式应急气象站:应急气象监测装备

TH-BQX5便携式应急气象站,作为现代气象监测的重要装备,以其独特的便携性、高效性和灵活性,在应急气象监测领域发挥着至关重要的作用。这类气象站不仅为灾害预警、环境保护、农业生产等多个领域提供了实时、准确的气象数据,还在突发…

uniapp通过Canvas绘制网格(心电图,坐标纸等可用)

本篇文档是Canvas绘制心电图的第一个部分&#xff0c;想了解详情的可以关注后学习交流。 心电图的最底层需要一个网状底层&#xff0c;来方便进行数据的测量。 一、白底分大、中、小三个区域的网格 1、首先是HTML部分 <!DOCTYPE html> <html lang"en">…

DNS设置(linux)

1.配置dns需要现在/etc/sysconfig/network-scripts/目录下的ifcfg-ens33(后面数字也可能是其他的)中配置DNS 2.编辑/etc/resolv.conf文件&#xff0c;将上面网卡中加的dns服务器ip添加到此文件 vi /etc/resolv.conf重启网络配置 service network restart常用的dns的ip 国内…

qt中实现多语言功能

qt中实现多语言功能 原理&#xff1a; 其本质就是生成ts文件&#xff0c;然后使用Linguist软件手工翻译&#xff0c;再生成qm文件&#xff0c;最后在主程序的开始加载不同的qm文件&#xff0c;实现多语言。 步骤&#xff1a; 修改程序文件 在pro文件中加入说明 TRANSLATI…

通讯录恢复怎么办?保护珍贵联系信息的2个必备技能!

手机通讯录扮演着重要的角色&#xff0c;它不仅仅是一个简单的联系方式列表&#xff0c;更是我们与亲朋好友、同事、业务伙伴等之间关系的见证。万一不慎丢失或误删通讯录&#xff0c;学会通讯录恢复的技能变得非常重要。本文将为你介绍几种保护珍贵联系信息的必备技能&#xf…

这样写代码太优雅了吧

文章目录 优化案例初次优化再次优化看看Spring源码的处理 优化案例 假设一个场景&#xff0c; 开发代码时&#xff0c;需要对类中的方法进行遍历&#xff0c;判断有没有注解NotNull&#xff0c;暂时没有合适的工具类&#xff0c;需要自己手搓一个。 无须多想&#xff0c;分分钟…

从GPT-3.5到GPT-4O:探索AI的进化之旅,哪一版更懂你?

如何评价GPT-4o? 最新的GPT-4O&#xff0c;被誉为GPT-4的增强版。它在保持前代产品优秀性能的基础上&#xff0c;大幅降低了使用成本&#xff0c;使得更多的普通用户也能享受到顶尖AI的服务。GPT-4O在非英语语言处理上的强化&#xff0c;更是让其在全球范围内的适用性大大提高…

使用Java和XxlCrawler获取各城市月度天气情况实践

目录 前言 一、历史数据获取 1、关于天气后报 2、信息界面分析 二、数据的提取开发 1、PageVo的定义 2、属性定义 3、实际信息抓取 三、信息抓取调试以及可能的问题 1、信息获取成果 2、关于超时的问题 四、总结 前言 这篇文章主要来源于一个我们家小朋友的一个作业…

FreeSwitch视频会议同时支持内网和外网接入

我们在使用freeswitch进行视频会议时&#xff0c;之前所有的用户都是通过外网的方式接入&#xff0c;因为fs给其返回的sdp协议内容里&#xff0c;只需要fs配置的外网IP就可以了&#xff1b;最近由于引入新的业务需要有其他内网的服务器也可以直接接入fs的视频会议房间&#xff…

【Spring Cloud】分布式配置

目录 未来的开发场景为什么需要配置中心配置实时生效配置管理流程 开源配置中心基本介绍DisconfSpring Cloud ConfigApolloNacos Spring Cloud Config介绍配置管理工具体系 案例需求编写 Config Server1.创建配置文件2.创建项目3.添加依赖4.添加注解5.修改配置文件application.…

玩游戏也能学好 JavaScript 啦?

最近有朋友问&#xff0c;应该如何学好 JavaScript。不过我做了好多年的后端开发&#xff0c;JavaScript 虽然也是有所接触&#xff0c;但肯定是谈不上精通。在将朋友介绍给公司的前端大神之后&#xff0c;突然想到&#xff0c;学习编程本身还是一个挺枯燥的事情&#xff0c;如…