关于抽象有感

本人菜鸟一枚,最近学习设计模式之余对于抽象忽有一丝明悟。因记性不好怕以后遗忘,便总结记录一下。如果错误,望分享指出。

首先说个栗子

在我初中那会,移动卡有专门移动的手机,联通有专门联通的手机,电信有专门移动的手机。

我记得高中那时候,我用了存了好久的钱在学校旁边的移动手机店里买了我人生的第一部手机,同时也买了一张移动的电话卡。

移动信号好,但是那玩意话费贵啊,流量也贵。那时候正好有大王卡出来,我就想换张联通的卡。结果搞了大王卡发现用不了,为什么呢?因为我是移动的手机,用不了联通的卡。那没办法,咋办?那时候又没钱只好等着换新手机,只是我心中暗暗下定决心下次一定要买一部全网通的手机。


抽象这个词其实就跟它的名字一样就很抽象。

搜狗汉语对他的解释为,「从许多事物中,舍弃个别的、非本质的属性,抽出共同的、本质的属性的过程,是形成概念的必要手段」

通过抽取一些事物的共同点,形成某种概念可以来概述形容这些事物。抽象是一个过程,抽象后得到的结果就是一类事物的统称。

比如说,水果,是苹果,梨子,橘子等等可以用水果的特点来形容的事物的统称。

那么,在程序中抽象的意义在哪里呢?我直接想要什么用什么不好吗?

在依赖倒置原则中,有这么一个说法「高层次的类不应该依赖于低层次的类。两者都应该依赖于抽象接口。抽象接口不应依赖于具体实现。具体 实现应该依赖于抽象接口。」

为什么这么做呢?其实通过最开始的例子就可以知道了。

电话卡可以当成一个抽象类或者接口,而移动卡,联通卡,电信卡可以当做是电话卡这个抽象的具体实现。如果把我们的手机当做一个函数,那么电话卡就是这个函数所需要的参数。也就是手机依赖电话卡,也就是我只要是电话卡就行了不用管是移动还是联通还是电信。但是如果是那种合约机,将参数定指定成了移动的。可能我最开始用没有差别,但是人生跟我们的项目一样都是不是一成不变的,可能有一点我需求变了,变成了联通卡。那怎么办呢,那就只能搞个联通的手机。如此往复,对于代码来说就是特别的冗余。对于生活来说,就是家里有矿。

「可以使程序的设计者把主要精力放在程序的设计上,而不必拘泥于细节的实现」

我觉得这句话把整个面向抽象的意义总结的很到位。程序设计者可以不用去管具体的实现方式是怎样的,因为细节是不断变化的。但是对于整个项目的架构来说,这一个块我可能只需要知道他有这个功能就行了。但是他怎么实现的,我不需要知道。这样有助于日后程序的扩展以及解耦,以不变应万变。

很多人都知道API接口,其实API跟程序内部的抽象接口也是有同理之处的。

对于API接口来说,我们只需要这个接口可以获取xx功能的数据,可以完成xx功能。API接口只需要给出一个具体的API文档,根据文档获取数据就行了。然后调用着根据返回的数据格式来使用数据。

那么对于抽象接口来说呢,其实也是一样的。每个抽象接口都规定了一些方法。然后所有实现了这个抽象接口的都必须实现这个方法,然后我不需要知道每个细节具体是怎么实现的。我只知道根据抽象接口的方法来使用就可以了。

API接口通过参数文档来约束自己,而抽象接口本身就是一个约束。

对于实际使用案例来说,举个例子。

假设我们对于数据库的需求只有增删改查4个功能,但是我们有不同的数据库,比如sqlserver,MySQL等等等等。

假如我们需要一个中间类来专门帮我们处理数据库的连接,到我们要传入针对每个数据库不同的dbhelper类。如果我们针对每个数据库都新建一个方法的话,那么假如数据库特别多呢?(别杠,这本来就是假设。为了举例子)

并且每个数据库的方法其实都差不多,就只要增删改查。

那么如果我们如果定义一个DB抽象类或者DB接口,约束了增删改查4个方法。然后接下来的所有数据库使用的Dbhelper类都继承DB接口。

这样接下来传入中间类的参数是不是就可以用DB接口来传递了,而我们使用的时候只需要传入对应的实现类就行了。同时在以后需求增加或者修改的时候,也不会影响中间类的参数。因为你只要继承这个DB接口就可以了。

在这里DB接口就相当于约束,所有继承他的类,都必须满足这个约束。

这整个数据模块,我需要增删改查我就只需要使用DB就行了,不需要去指定的依赖具体的实现类。具体的,你什么时候使用什么时候指定就行了。也就是前文所说,「可以使程序的设计者把主要精力放在程序的设计上,而不必拘泥于细节的实现」。

个人认为,软件工程师,主要体现在工程师三字。工程师与工人的差别,一个是把高楼设计出来,而一个是根据设计将高楼做出来。

愿你我前程似海奔腾万里
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。