你听说过停车场的挑战吗?如果没有,让我简单地解释一下。
停车场是一项挑战,要求你编写一个管理假想停车场的类。
在本教程中,我们将用JavaScript来完成这个任务。为了让它更有趣,我们将创建一个小的React应用程序,以可视化的方式展示我们的类的工作情况。
让我们开始吧。🎉
挑战要求
在这个挑战中,你必须用JavaScript实现一个类。这个类应该由变量和方法组成,模拟停车场的工作方式。以下是具体内容:
- 我们应该能够创建具有特定大小(停车位数量)的停车场。
- 我们不区分不同的车辆 - 我们认为它们都是一样的
- 我们的类提供了一个将新车停放在停车场的方法
- 我们的类提供了一个移除已停放车辆的方法,以及
- 我们的类提供了一种方法来获得停车场的大小(停车位的总数)。
停车场的挑战解决方案
首先,让我们看一下类的逻辑本身。
它非常简单明了,所以对你们中的大多数人来说可能不会有任何惊喜--特别是如果你已经有一些OOP和基于类的语言的编程经验。
类ParkingLot
我将首先给你代码,然后我将对实现进行简短的解释:
class ParkingLot {
slots = [];
constructor(parkingSize) {
this.slots = new Array(parkingSize).fill(null);
}
park(carId) {
console.log(`Parking car: ${carId}`);
if (this.slots.every((slot) => slot !== null)) {
return false;
}
for (let i = 0; i <= this.slots.length; i++) {
const slot = this.slots[i];
if (slot === null) {
this.slots[i] = carId;
return true;
}
}
}
remove(carId) {
console.log(`Leaving car: ${carId}`);
if (this.slots.every((slot) => slot !== carId)) {
return false;
}
for (let i = 0; i <= this.slots.length; i++) {
const slot = this.slots[i];
if (slot === carId) {
this.slots[i] = null;
return true;
}
}
}
getSlots() {
console.log(`Parking slots: ${this.slots}`);
return this.slots;
}
getSize() {
console.log(`Parking size is: ${this.slots.length}`);
return this.slots.length;
}
getAvailable() {
const availableSlots = this.slots.filter((s) => s === null).length;
console.log(`Available parking slots: ${availableSlots}`);
return availableSlots;
}
isFull() {
return this.getAvailable() === 0;
}
}
export default ParkingLot;
从头开始--我们的类有一个属性,slots ,这将是一个数组,用于存储关于停车位的信息(无论它们是空闲还是被占用)。
然后,我们有一个constructor 方法,在你每次创建这个类的实例时都会执行。在这里,我们使用一个输入的数字参数,称为parkingSize ,来创建一个长度等于该数字的空数组。
从技术上讲,这个数组不是空的,因为我们用空值初始化它。这意味着,在构造函数中执行代码后,我们最终会得到一个充满空值的数组,这取决于我们传入的数字。
例如,如果我们执行这个:
const parking = new ParkingLot(5);
它的结果将是这样的:
[null, null, null, null, null] // lenght = 5
instead of [] // empty array, length 0
在经历了构造函数之后,让我们来看看这个类中的其他方法。
park() - 这就是我们实际停车的地方。这个方法在 数组上进行迭代,检查是否有空位(即仍等于null的槽),并在这些空位上添加汽车。slots
汽车是由carId 。这只是一个标识符,我们用它来表示我们有一辆车在某个位置。注意,如果没有空位,这个方法返回false,如果停车成功,则返回true。
getSlots() - 帮助方法,只是返回我们用来存储停车位的数组。
remove() - 这就是我们如何从停车场移除汽车的方法。这个方法也是对车位数组的迭代。
到目前为止,你可能已经注意到,在几乎所有的情况下,当我们需要操作存储在数组这样的数据结构中的数据时,我们必须对这个结构进行迭代,以便我们能够访问它的元素。
不同的编程语言提供了不同的数据结构和方法来处理它们,但主要的想法总是相同的:当你需要对这些数据做什么时,你需要以某种方式迭代它。
为了从停车场移走一辆车,我们使用上述的标识符。我们在slots数组中寻找这样的项目,如果我们得到一个匹配,我们就有一辆车可以 "取消停车"。我们通过再次将那个特定的槽设置为空来执行实际的移除。
现在你可以猜到为什么我们一开始就决定用null来初始化我们的slots数组。
这个方法也会返回一个布尔值的结果,取决于是否成功移除。
在建立某种能够对这种变化作出反应的用户界面时,我们应该能够使用这种反馈。在向停车场添加汽车时也是如此(请看park 方法)。
getSize() - 另一个帮助方法,我们用来检查停车场的大小。
getAvailable() - 这个告诉我们目前有多少个可用的车位。
isFull() - 告诉我们,如果停车场已经满了,就是没有可用的车位了。
如何构建React应用程序
停车场应用程序 - 主屏幕
这里是有趣的开始。🕺
我们将创建一个交互式应用程序,将我们可以在上述实现的帮助下执行的任务可视化。
我们的应用程序将提供基本的用户界面控制,允许一个(假想的)操作员与停车场软件一起工作*。* 为了使他们的工作更加赏心悦目,我们将尝试把我们的软件提供的基本功能做成动画。
让我们来看看如何!📺
源代码
这里是该应用程序的源代码的repo。
让我给你一个关于什么和为什么的简单总结。
该应用程序是用vite构建的。原因是我最近一直在使用它,我对它的速度和性能非常满意。
不管它仍然处于相对早期的开发阶段--如果我即将开始一个新的项目,并处于可以选择的位置,我将选择vite。
这并不是说我对它的老大哥CRA有什么意见。相反,我已经用它建立了多个应用程序,而且我仍然在我的一些项目中使用它。只是vite要快得多,而且经常能提供我目前需要的一切。
💡请记住,选择一种特定的技术总是取决于你对特定项目的具体需求。这就是说,没有什么银弹。它始终是一个需求和优先级的问题。
React应用程序的结构
应用程序的结构
该应用程序的结构是直接的。在根层,我们有两个文件夹--assets和src。第一个文件夹包含应用程序中使用的资产(在本例中,它只是一个汽车图片)。后者包含所有的源代码文件。
让我们仔细看看source文件夹中的内容。
这里我们有以下文件夹:
- components- 包含应用程序中使用的所有React组件
- lib- 包含停车场类,负责应用程序的主要逻辑
- pages- 包含两个子目录,分别用于应用程序中的两个主要屏幕--Landing和Main,。
- utils- 包含一个帮助方法,用于生成虚构的汽车牌照,我们以后在表示停车位繁忙时使用该方法。
- 还有几个文件,其中大部分与应用程序的入口点有关,除了favicon文件 - 它们的作用对你来说应该很清楚。如果没有,请看一下你的浏览器的标签😉。
带图标的浏览器标签
应用程序页面
如前所述,应用程序中的主要页面(也称为屏幕)被称为Landing和Main。这些都是React组件本身。它们作为你在欢迎页面中看到的一切的骨架--你最初登陆的地方,以及你可以选择你想在停车场中拥有多少个停车位的地方。
欢迎页面
点击大的、ping的提交按钮后进入的页面--你的操作员能够管理停车场的主屏幕。
主页面
应用程序的功能
该应用程序为管理一个假想的停车场提供了非常基本的功能。当用户选择他们想要的插槽数量(最多20个),他们将被过渡到主屏幕。在那里,用户将能够看到所有的免费停车位。
当一辆车被停放时,通过PARK!按钮,相关的位置将被可视化为繁忙状态,并将显示正在停放的汽车的注册号码。操作员可以通过点击繁忙的车位,也就是他们想从停车场 "移除 "的汽车,来解除汽车的停放。
💡移动的红色汽车的简单动画只是为了视觉效果,对停车场的工作方式没有任何实际影响。
我使用CSS模块来设计应用程序的风格。我还试图使这个应用程序对移动设备友好一些,以防你决定在你的移动设备上尝试。
做我的客人,试试吧 🧪
结论
我在这篇文章背后的最初想法是描述停车场类本身。你知道,只是为了教育目的。向你展示如何用JavaScript编写这样一个类。
但后来我觉得这有点无聊🥱。 我想创造一些更有趣的东西💃🏻,一些更游戏化的东西🕹️可以这么说。
这就是我为什么要做这个类似于迷你游戏的应用程序的原因。
在制作过程中,我5岁的女儿🧒🏻看到了它,并想和它玩。实际上她玩得很开心!
是的,是的,当然了!我并不是说,如果这对一个5岁的孩子来说是有趣的东西,那么对你来说也是如此😀。
我唯一的目标是通过游戏吸引你的注意力,让它背后的知识📖在你身上停留更久。
谢谢你的阅读!🙏