面向对象系列讲解—面向对象的含义&工厂模式

HTML5学堂:在上一篇文章当中,我们把对象进行了基本的解释,本文当中,我将为大家解释什么是面向对象?为何要使用面向对象,而不用面向过程,面向对象又有什么好处,能够帮我们做些什么?基本的面向对象的代码又应当如何书写?并依照以上的例子来讲解一下“工厂模式”。

面向对象的解释

对面向对象的解释如下:把数据及对数据的操作方法放在一起,作为一个相互依存的整体——对象。对同类对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,对象与对象之间通过消息进行通信。

看不懂?没关系,且听我稍微解释一下。其实,在我们生活中,有很多面向对象的例子,比如我们使用的电脑,我们借助什么来给计算机传递信息,又借助什么看到计算机是否执行了自己想要的操作?——很明显,采用键盘和鼠标(还有话筒等)给计算机传入信息,然后计算机通过电脑屏幕给我们呈现出信息出来。至于我们按下键盘之后,计算机是如何识别的,如何转化成二进制数值进行运算,又是如何运算,然后什么二极管是如何传递信息,电子屏又是如何构成的,我们并不清楚,也不必清楚。那么这个电脑就称之为一个对象,我们并不需要了解它内部的运行机制,只需要了解如何操作它(键盘、鼠标)——即所谓的外部接口。知道它会给我们传递出什么就可以了。

不知道上面的例子有没有解释清楚,再举一个电视的例子,我们只需要知道按下遥控器的哪个键能够做什么就足够了,至于电视机是如何实现的这个功能我们不需要了解。这个遥控器就相当于我们能够操作电视机这个“对象”的“接口”。

为何要使用面向对象

面向对象的好处是什么呢?在我们的代码开发当中,对于一些功能,可能在某些网页当中是重复出现的,那么此时,我们完全可以把这部分功能封装成一个对象,然后在多个地方进行调用,而不是每次遇到它的时候都重新书写一次。

大概能够明白了吧?其实,是我们实在是不希望复制粘贴,太麻烦了。而且复制粘贴的话,一个网页中代码量会“暴涨”,网页读取加载速度自然就慢了,那用户对着空白的屏幕要等待更长的时间,这种情况下,还有谁来看我们的网页呢?所以,从开发者到用户再到我们的公司,采用面向对象的编程方式都是有好处且有必要的。

面向对象代码实例:话不多说,我们来写一个实际的面向对象的例子。先来回顾一下我们上篇文章中的那段代码:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>面向对象-独行冰海</title>
</head>
<body>
    <script>
        var obj = {};
        obj.username = '独行冰海';
        obj.blogsrc = 'http://blog.163.com/hongshaoguoguo@126';
        obj.weibo = 'http://weibo.com/u/2706684357';
        obj.showInf = function (){
         alert('姓名:'+obj.username+'\n博客地址:'+obj.blogsrc+'\n微博地址:'+obj.weibo);
        }
        obj.showInf();
    </script>
</body>
</html>

我们会发现这个代码不能够通用,很不好,如果我希望创建另一个人的基本信息,还需要新建,那么我们利用参数,对函数进行修改。

修改后的代码如下:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>面向对象-独行冰海</title>
</head>
<body>
    <script>
        function createPerson(username, blogsrc, weibo){
            var user = new Object();
            user.username = username;
            user.blogsrc = blogsrc;
            user.weibo = weibo;
            user.showInf = function (){
                alert('姓名:'+this.username+'\n博客地址:'+this.blogsrc+'\n微博地址:'+this.weibo);
            }
            return user;
        }
        var user1 = createPerson('独行冰海', 'http://blog.163.com/hongshaoguoguo@126', 'http://weibo.com/u/2706684357');
        user1.showInf();
    </script>
</body>
</html>

来说说这段代码修改了什么地方:

1、将需要呈现的基本信息作为参数传递到函数当中,而不是单独创建变量;

2、添加了return的功能,这处是在执行之后返回user这个对象;

3、obj的定义采用了new Object(); 用于实例化一个对象;

4、alert中的obj.username等修改为this.username,关于this,这里this指向的就是obj,因此可以使用this对其进行替换,在此这个地方不再做详细的解释了,如果不是很清楚this指向的话,可以参见日志《this 的使用方法 —— javascript中的this讲解!》《this的使用方法,补充讲解 —— javascript中的this讲解》;

5、考虑代码阅读性方面的问题,修改了obj的命名为user。

将代码写到此,我们实际上就已经实现了工厂方式的构造方法。

什么是工厂模式

先来解释一下工厂模式。工厂是什么概念呢?很简单。工厂模式需要三个基本步骤,原料投入、加工过程以及成品出厂。 来看一下这段代码当中,var user = new Object(); 以及 函数中传递的参数就是“基本原料的投入”;具体从user.username一直到return之前,都属于“加工过程”;最后的return就如同“成品出厂”。

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>面向对象-独行冰海</title>
</head>
<body>
    <script>
        function createPerson(username, blogsrc, weibo){
            // 原料的投入
            var user = new Object();
            // 加工过程的开始
            user.username = username;
            user.blogsrc = blogsrc;
            user.weibo = weibo;
            user.showInf = function (){
             alert('姓名:'+this.username+'\n博客地址:'+this.blogsrc+'\n微博地址:'+this.weibo);
            }
            // 加工过程的结束
            // 成品出厂
            return user;
        }
        var user1 = createPerson('独行冰海', 'http://blog.163.com/hongshaoguoguo@126', 'http://weibo.com/u/2706684357');
        user1.showInf();
    </script>
</body>
</html>

接下来说说工厂方式的缺陷:

1、没有new,也就是没有构造函数实例化的过程——其实也就是语义性不是很好;

2、对于此种构建,会为每个实例化的对象都创建相应的变量和函数。也就是,创建了多个空间进行属性和方法的存储。从而降低了性能,产生资源浪费。

来解释一下第二个缺陷是什么意思。在createPerson这个函数之后的内容修改为如下代码:

var user1 = createPerson('独行冰海', 'http://blog.163.com/hongshaoguoguo@126', 'http://weibo.com/u/2706684357');
console.log(user1.showInf);
var user2 = createPerson('独行冰海', 'http://blog.163.com/hongshaoguoguo@126', 'http://weibo.com/u/2706684357');
console.log(user2.showInf);
console.log(user1.showInf == user2.showInf);

在谷歌控制台当中打印出的内容如下:

能够看出来,打印出的两个函数内容完全相同,但是比较之后却返回的是false

可见,使用工厂方式创建的对象,在调用的时候会创建多个属性和方法。当创建的对象比较多的时候,会在空间中创建多个空间进行存储,从而造成了资源浪费。

那么如何解决这种问题呢?我们可以采用混合模式的书写方法,使用new去解决这种工厂模式的缺陷,利用原型解决“方法”的重复创建,这种方法也是最为常用的方法。

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2016-02-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

4818
来自专栏菩提树下的杨过

Flash/Flex学习笔记(23):运动学原理

先写一个公用的小球类Ball: package{ import flash.display.Sprite; //小球 类 public class B...

25210
来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2132
来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.2K7
来自专栏张善友的专栏

Mix 10 上的asp.net mvc 2的相关Session

Beyond File | New Company: From Cheesy Sample to Social Platform Scott Hansel...

2527
来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3095
来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

2625
来自专栏hbbliyong

WPF Trigger for IsSelected in a DataTemplate for ListBox items

<DataTemplate DataType="{x:Type vm:HeaderSlugViewModel}"> <vw:HeaderSlug...

4054
来自专栏大内老A

The .NET of Tomorrow

Ed Charbeneau(http://developer.telerik.com/featured/the-net-of-tomorrow/) Exciti...

30810
来自专栏跟着阿笨一起玩NET

c#实现打印功能

2622

扫码关注云+社区