面向对象编程的四大支柱

2020年12月30日10:40:54 发表评论 36 次浏览

本文概述

JavaScript是一种多范式语言, 可以按照不同的编程范式编写。编程范例本质上是你在编写代码时遵循的一堆规则, 以帮助你解决特定问题。

这就是四个支柱。它们是软件设计原则, 可帮助你编写简洁的面向对象的代码。

面向对象编程的四个支柱是:

  • 抽象化
  • 封装形式
  • 遗产
  • 多态性

让我们仔细看看它们中的每一个。

删除某些东西意味着隐藏一些东西内部的实现细节, 有时是原型, 有时是函数。因此, 当你调用该函数时, 不必完全了解其功能。

如果你必须了解大型代码库中的每个函数, 就永远不会编写任何代码。阅读所有内容可能需要几个月的时间。

你可以通过抽象掉某些细节来创建可重用, 易于理解且易于更改的代码库。让我举一个例子:

function hitAPI(type){
	if (type instanceof InitialLoad) {
		// Implementation example
	} else if (type instanceof NavBar) {
		// Implementation example
	} else {
		// Implementation example
	}
}

根本没有抽象。

你可以在示例中看到如何完全实现自定义用例所需的内容吗?

你需要使用的每个新API都需要一个新if块, 它是自己的自定义代码。由于你需要担心所添加的每种新类型的实现, 因此并未将其抽象化。它不可重用, 并且是维护的噩梦。

像下面这样的东西怎么样?

hitApi('www.kealanparr.com', HTTPMethod.Get)

现在, 你只需将URL传递给函数以及要使用的HTTP方法即可完成。

你不必担心该功能如何工作。处理了。这极大地帮助了代码重用!并且也使你的代码更具可维护性。

那是什么抽象化关于一切。查找代码中相似的事物, 并提供通用的函数或对象来服务多个地方/涉及多个问题。

这是一个很好的最终例子抽象化:想象一下你是否正在创建一台为用户制作咖啡的机器。可能有两种方法:

如何用抽象创建它

  • 有一个标题为"煮咖啡"的按钮

如何在没有抽象的情况下创建它

  • 有一个标题为"煮水"的按钮
  • 有一个标题为"向水壶添加冷水"的按钮
  • 有一个标题为"将1勺研磨咖啡添加到干净的杯子中"的按钮
  • 有一个标题为"清洁所有脏杯子"的按钮
  • 还有所有其他按钮

这是一个非常简单的示例, 但是第一种方法摘要将逻辑转移到机器中。但是第二种方法迫使用户了解如何煮咖啡以及基本上是自己煮咖啡。

下一个支柱向我们展示了我们可以实现的一种方法抽象化, 通过使用封装。

封装的定义是"将某物封装在胶囊中或好像封装在胶囊中的动作"。删除对代码部分的访问并使其私有化是正确的封装形式全部有关(通常, 人们称其为数据隐藏)。

封装意味着代码中的每个对象都应控制自己的状态。状态是对象的当前"快照"。键, 对象上的方法, 布尔属性等。如果你要重置布尔值或从对象中删除键, 它们都是对你状态的更改。

限制代码可以访问的部分。如果不需要, 则使更多的东西无法访问。

私有属性是通过使用闭包在JavaScript中实现的。下面是一个示例:

var Dog = (function () {

	// Private
	var play = function () {
		// play implementation
	};
    
	// Private
	var breed = "Dalmatian"
    
	// Public
	var name = "Rex";

	// Public
	var makeNoise = function () {
 		return 'Bark bark!';
	};

 	return {
		makeNoise: makeNoise, name: name
 	};
})();

我们要做的第一件事是创建一个立即被调用的函数(称为立即调用函数表达式, 或简称IIFE)。这创建了一个任何人都可以访问但隐藏了一些细节的对象。你不能打电话玩而且你无法访问品种因为我们没有在返回的最终对象中公开它。

上面的这种特殊模式称为显示模块模式, 但这只是如何实现的一个示例封装。

我想更专注于封装形式(因为它比仅学习一种模式和计数更为重要封装形式完全完成)。

反思, 并更多地考虑如何隐藏数据和代码, 并将其分离出来。模块化和明确职责是实现目标的关键面向对象.

为什么我们应该偏爱隐私?为什么不将所有事物都全球化?

  • 许多不相关的代码位将通过全局变量相互依赖/耦合。
  • 如果名称被重用, 你可能会覆盖变量, 这可能导致错误或不可预测的行为。
  • 你可能最终会得到意大利面代码–难以推理并遵循对变量的读写操作和状态更改的代码。

可以通过将较长的代码行分成较小的单独函数来应用封装。将这些功能分成模块。我们将数据隐藏在其他任何人都不需要访问的地方, 并干净地暴露所需的内容。

那是封装形式简而言之。将你的数据绑定到某个东西, 无论是类, 对象, 模块还是函数, 并尽力将其尽可能地私有化。

继承使一个对象可以获取另一对象的属性和方法。在JavaScript中, 这是通过原型继承.

可重用性是这里的主要好处。有时, 我们知道多个地方需要做同一件事, 除了一小部分, 他们需要做的所有事情都一样。这是继承可以解决的问题。

每当我们使用继承时, 我们都会尝试使其继承, 以使父级和子级拥有高凝聚力。凝聚你的代码的相关性。例如, 鸟从类型扩展柴油发动机类型?

使你的继承简单易懂且可预测。不要从完全不相关的地方继承, 因为你需要一种方法或属性。继承不能很好地解决该特定问题。

使用继承时, 你应该需要大多数功能(并非总是绝对需要所有功能)。

开发人员有一个称为里斯科夫换人原则。它指出如果你可以使用父类(让我们称之为父类型)在你使用孩子的任何地方(让我们称之为子类型)–和子类型继承自父类型–然后你通过了测试。

你将无法通过此测试的主要原因是, 如果子类型正在从父母那里移除东西。如果子类型删除了它从父级继承的方法, 这会导致TypeError是你未期望的未定义的地方。

面向对象编程的四大支柱1

箭头看起来像是走错了方向。但是动物是基础-父母。

继承链是一个术语, 用于描述从基础对象的原型(其他所有内容都从其继承的原型)到继承链的"末端"(继承的最后一种类型)的继承流程。狗在上面的示例中)。

尽最大努力使你的继承链保持清洁和合理。你可以在使用时轻松结束对反模式的编码继承(叫做脆弱的基础反模式)。 这种情况发生在你的基础原型被视为"脆弱"的情况下, 因为你对基础对象进行了"安全"更改, 然后开始破坏所有子对象。

多态性是指"以几种不同形式出现的条件"。这正是第四个也是最后一个支柱所关心的-同一继承链中的类型能够执行不同的操作。

如果正确使用了继承, 你现在就可以像父母的孩子一样可靠地使用父母。当两种类型共享一个继承链时, 它们可以互换使用, 并且代码中没有错误或断言。

在上一张图中, 我们可能有一个称为动物定义制造吵闹声。然后, 从该原型扩展的每种类型都可以覆盖以执行自己的自定义工作。像这样:

// Let's set up an Animal and Dog example
function Animal(){}
function Dog(){}

Animal.prototype.makeNoise = function(){
	console.log("Base noise");
};

// Most animals we code up have 4. This can be overridden if needed
Animal.prototype.legs = 4;

Dog.prototype = new Animal();

Dog.prototype.makeNoise = function(){
	console.log("Woof woof");  
};

var animal = new Animal();
var dog = new Dog();

animal.makeNoise(); // Base noise
dog.makeNoise();    // Woof woof- this was overridden
dog.legs;           // 4! This was inherited

狗从...延伸动物并可以使用默认值腿属性。但是它也可以自己制造噪音。

多态的真正力量在于共享行为, 并允许自定义替代。

我希望这已解释了面向对象编程的四个支柱是什么, 以及它们如何导致更简洁, 更健壮的代码。

我分享我的文章推特如果你喜欢这篇文章并想了解更多。

一盏木

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: