首页 > 代码库 > 面向对象思维的编程方式

面向对象思维的编程方式

前言:

通常来说,我们在没有任何目的性的组织代码,所有的代码逻辑都是根据程序员理解到哪一步业务就写到哪一步的代码写法,称之为面向过程的编程。面向过程的编程,是纯粹的以程序员的代码流程,来控制整个项目的业务实现,这样的代码通常具有比较强的耦合性,通常涉及到修改代码,很可能就是一个比较繁杂的过程,需要修改很多的代码,需要思维重现编写该代码的程序员的思考流程。不得不说,这样的代码组织方式不利于后期维护以及修改。

什么是面向对象的编程?

面向对象的编程,理论核心就是将每一个功能模块进行抽离,然后封装成对象,赋予每个功能模块抽离的对象相应的属性,包括该模块需要的数据部分,以及该模块需要与外界进行联动沟通所需要的方法部分。

 1 var obj = {
 2     name: `name1`,
 3     id: `id2`,
 4     dosomeThing: function() {
 5         console.log(`${this.id}:${this.name}`);
 6     },
 7     dosomeThing2: function(num) {
 8         console.log(`外部的变量${num} : 对象自带的属性${this.name}`);
 9     }
10 }
11 
12 
13 obj.dosomeThing(); //id2 : name1
14 
15 obj.dosomeThing2(); //外部的变量undefined : 对象自带的属性name1
16 
17 obj.dosomeThing2(5); //外部的变量5: 对象自带的属性name1

我们可以使用这种方式,将所有的模块抽离并封装成对象,降低模块与模块之间的耦合性,提交代码的可维护性与可读性,我们每个模块都有自己的实例化对象,所有的逻辑我们只需要在对象的方法中进行处理。

但是,这种程度的封装,也有一定的缺陷,如果项目中存在多个重复的模块,很有可能,我们可能需要多次重复生成基本一致的对象来进行操作,会导致我们的代码中存在很多的重复代码,这些冗余的代码,也会导致代码的可读性变差,同时增加维护成本。

面向对象的封装、继承、多态

面向对象有三个最重要的部分,就是封装、继承、多态。以上的用法不难发现,只能支持封装部分,而无法实现继承与多态,如果需要自己去实现深拷贝,也是能够达到这样的效果,但是太过繁琐。

 1 var objCopy = function(obj) {
 2     var tmp_obj;
 3     if(typeof obj == ‘object‘) {
 4         if(obj instanceof Array) {
 5             tmp_obj = [];
 6         } else {
 7             tmp_obj = {};
 8         }
 9     } else {
10         return obj;
11     }
12     for (var i in obj) {
13         if (typeof obj[i] != ‘object‘) {
14             tmp_obj[i] = obj[i];
15         } else if (obj[i] instanceof Array) {
16             tmp_obj[i] = [];
17             for (var j in obj[i]) {
18                 if (typeof obj[i][j] != ‘object‘) {
19                     tmp_obj[i][j] = obj[i][j];
20                 } else {
21                     tmp_obj[i][j] = ObjCopy(obj[i][j]);
22                 }
23             }
24         } else {
25             tmp_obj[i] = ObjCopy(obj[i]);
26         }
27     }
28     return tmp_obj;
29 }
30  
31 var obj2 = objCopy(obj);
32 
33 obj2.dosomeThing3 = function() {
34     console.log(`test`);
35 } 

不难发现,这种方式确实能够达到目的,但是这种继承的方式,毕竟比较怪异,而且因为通过深拷贝生成的子对象,实际上并没有在原型链上有直接关联。我们通常会使用另外一种方式来定义对象。

function parent(name, id) {
    this.name = name;
    this.id = id;
}
parent.prototype.dosomeThing = function() {
    console.log(`${this.name}:${this.id}`);
}

var obj1 = new parent(`name1`, `id2`);
obj1.dosomeThing(); //name1:id2

var obj2 = new parent(`name11`, `id22`);
obj2.dosomeThing(); //name11:id22

obj2.dosomeThing3 = function() {
    console.log(`test`);
}

obj2.dosomeThing3(); //test

function child(name, id) {
    parent.call(this, name, id);
}
child.prototype = Object.create(parent.prototype);
child.prototype.dosomeThing4 = function() {
    console.log(`hehe`)
}

obj2.dosomeThing4(); //hehe

var obj3 = new child(`dy`, `001`);

obj3.dosomeThing4(); //hehe

obj3.dosomeThing5 = function() {
    console.log(`hehe2`)
}

obj2.dosomeThing5; //undefined

obj3.dosomeThing5(); //hehe2

这种方式通过原型链来进行继承以及通过new来生成实例化对象,可以提取公共代码,同时通过继承,并添加私有的方法来达到多态

面向对象思维的编程方式