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

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

在这里插入图片描述

我当时是这样设计的,创建两个类: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,应该由李四自己提供改变生命状态的方法,张三砍人的动作就是调用李四提供的这个方法。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多语言印度红绿灯系统源码带三级分销代理功能

前端为2套UI,一套是html写的,一套是编译后的前端 后台功能很完善,带预设、首充返佣、三级分销机制、代理功能。 东西很简单,首页就是红绿灯的下注页面,玩法虽然单一,好在不残缺可以正常跑。

短视频脚本创作的五个方法 沈阳短视频剪辑培训

说起脚本,我们大概都听过影视剧脚本、剧本,偶尔可能在某些综艺节目里听过台本。其中剧本是影视剧拍摄的大纲,用来指导影视剧剧情的走向和发展,而台本则是综艺节目流程走向的指导大纲。 那么,短视频脚本是什么&#xf…

XV7011BB可为智能割草机的导航系统提供新的解决方案

智能割草机作为现代家庭和商业草坪维护保养的重要工具,其精确的定位和导航系统对于提高机器工作效率和确保安全运行至关重要。在智能割草机的发展历程中,定位和导航技术一直是关键的创新点。 传统的基于RTK(实时动态差分定位技术)技术的割草机虽然在…

mysql连接不上可能的原因:防火墙放行mysql的3306端口 全库复制:data目录替换即可 mysql查看版本

1.看本地localhost能否连接 2.在本地看IP能否连接 能说明本地正常 权限也够 都能的话,ip能否ping通 能就说明可能是防火墙原因了。关闭防火墙及杀毒试试。 我这里关防火墙就能访问了。 windows如何开启防火墙,又放行mysql的3306端口? 在 …

可视化大屏也在卷组件化设计了?分享一些可视化组件

hello,我是大千UI工场,这次分享一些可视化大屏的组件,供大家欣赏。(本人没有源文件提供)

微前端(无界)入门

主应用通过props给子应用传值 父子应用通过eventBus通信 通过路由同步实现记录子应用的路由状态 主应用 main.ts: import ./assets/main.cssimport { createApp } from vue import { createPinia } from pinia import WujieVue from wujie-vue3import App from ./App.vue impo…

STM32 OTA需要注意问题

一、OTA设计思路(问题) 1、根据stm32f405 flash分布,最初将flash划分为四个区域,分别是Bootloader、APP1、APP2、参数区,设备上电后,进入Bootloader程序,判断OTA参数,根据参数来确定…

长方形边框 上方中间有缺口 css

<div class"text_6">大234234师掌4234柜</div><div class"text-wrapper_1"><span class"paragraph_1">四川慧创云戈科技有限公司推出的“大师掌柜”&#xff0c;是一个以餐饮外卖为切入口&#xff0c;专注实体小店新零售…

实验七 RTP、DSPP协议的配置

一、实验目的 掌握 RIP 动态路由协议的配置、诊断方法。 二、实验步骤 1、 运行 Cisco Packet Tracer 软件&#xff0c;在逻辑工作区放入两台路由器、两台工作站 PC&#xff0c;分别点击各路由器&#xff0c;打开其配置窗口&#xff0c;关闭电源&#xff0c;分别加入一个 2 …

PowerPivot-跨表取值

在PowerPivot中&#xff0c;跨表取值通常涉及创建关系和使用DAX&#xff08;数据分析表达式&#xff09;函数。 以下是一些基本步骤和常用的DAX函数&#xff0c;帮助你在PowerPivot中实现跨表取值&#xff1a; 步骤1&#xff1a;创建关系 加载数据&#xff1a;确保你已将需要…

吃透一道题day2:Java算法中的“如何找到给定字符串中的不同字符“

写在开头&#xff1a;很久没有开启有关算法的内容了,在正式开启开启今天这段算法之旅之前,跟大家谈一谈上周五歌手也就是第二期我的一些直观感受:相比第一期(chante moore的if i aint got you和faouzia的crazy带给我的经验)没有任何特别的惊艳之处,很平淡甚至可以说是心如止水,…

E. Binary Deque[双指针好思维题]

Binary Deque 题面翻译 有多组数据。 每组数据给出 n n n 个数&#xff0c;每个数为 0 0 0 或 1 1 1 。你可以选择从两边删数&#xff0c;求至少删几个数才可以使剩下的数总和为 s s s 。 如果不能达到 s s s &#xff0c;则输出 − 1 -1 −1 。 题目描述 Slavic h…

性能测试(基于Jmeter)

性能指标 RT&#xff08;Response Time&#xff09;响应时间&#xff1a;指的是用户从客户端发起请求开始到服务端返回结束&#xff0c;整个过程所耗费的时间 HPS&#xff08;Hits Per Second&#xff09;&#xff1a; 每秒点击次数&#xff0c;单位&#xff1a;次/秒 TPS&am…

Element-Plus中表格及分页功能

导入Element-Plus 具体步骤如下&#xff1a;&#xff08;内容参照官网&#xff1a;安装 | Element Plus&#xff09; # 选择一个你喜欢的包管理器# NPM $ npm install element-plus --save# Yarn $ yarn add element-plus# pnpm $ pnpm install element-plus 在main.js文件的…

树与图的深度优先遍历

数和图的存储方式与遍历 数和图的存储方式&#xff1a; 一般有两种 树是一种特殊的图&#xff08;即无环联通图&#xff09;。所以下面只讲图。 图的话分为两种&#xff1a;①有向图&#xff08;边是有方向的&#xff1a;a➡️b&#xff09;和 ②无向图&#xff08;边是无方…

安全设计 | Microsoft 威胁建模工具Threat Modeling Tool安装、使用及威胁生成原理详解(文末附样例)

1. 概览 微软威胁建模工具&#xff08;Threat Modeling Tool&#xff09;是 Microsoft 安全开发生命周期 (SDL&#xff0c;Security Development LifeCycle) 的核心要素。 当潜在安全问题处于无需花费过多成本即可相对容易解决的阶段&#xff0c;软件架构师可以使用威胁建模工…

断开自定义模块与自定义库的链接

断开自定义模块与自定义库的链接 1、断开模块与库的链接 1、断开模块与库的链接 如果摸个库文件添加到模型中&#xff0c;无法“Disable Link”时&#xff0c;可以使用save_system命令进行断开到模型中用户定义的库模块的链接&#xff1b; 参考链接&#xff1a; 传送门 save…

Python词法和语法分析工具库之ply使用详解

概要 在编程语言的开发、编译器的实现和数据解析等领域,词法分析和语法分析是关键的技术。Python的ply库是一个功能强大的词法和语法分析工具,基于经典的Lex和Yacc工具实现。ply库为开发者提供了一种简单且高效的方法,用于定义词法规则和语法规则,从而实现对自定义语言和数…

现货白银交易点差是多少

现货白银投资者通过交易平台进行买卖操作的时候&#xff0c;平台会以“点差”的形式向投资者收取一定的交易费用。所谓的点差&#xff0c;也就是平台所报出的买入价和卖出价之间的固定差额&#xff0c;由于现货白银的报价是“成对”的&#xff0c;所以点差的存在也是其交易模式…

【SpringMVC】_SpringMVC项目返回HTML与JSON

目录 1. SpringMVC项目返回HTML页面 2. SpringMVC项目返回JSON 2.1 程序演示 2.2 关于响应的Content-Type 2.2.1 接口为对象 2.2.2 接口为String 2.2.3 接口为Map 本专栏已介绍&#xff1a; 返回静态页面&#xff1a; 【Spring MVC】_SpringMVC项目返回静态页面_mvc 返…