前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >随笔编程杂谈录:[-封装-]

随笔编程杂谈录:[-封装-]

作者头像
张风捷特烈
发布2019-03-04 10:28:45
3920
发布2019-03-04 10:28:45
举报

制造轮子和创造轮子两者的区别在于:一者为复用,一者为封装

一、与封装的初遇

现在回到第一次我接触封装的时候:

两年前,class这个词进入了我的世界,但class并不是我封装思想的启蒙师。 在此之前,让我初次领略封装的强大之物是电子元件的引脚和它的真值表。 下面的例子希望你可以好好理解一下:怎么在逻辑上实现一位二进制的加法的逻辑运算单元 如果你看不下去,就直接return到第6小点

1.与门(AND)和非门(NOT)

你觉得很简单?(少年,你对于力量一无所知) 下面的两个东西的组合是计算机逻辑单元的一切

与门和非门
与门和非门
代码语言:javascript
复制
------与门真值表--------------------------非门真值表----------
 输入A  输入B   输出Y                   输入A   输出Y   
 0      0       0                       0       1
 0      1       0                       1       0
 1      0       0                       
 1      1       1     
 -------------------------------------------------------------
 简单解释一下: A和B你可以看成两根导线,只有高电平和低电平两种形式  
 1代表高电平,0代表低电平: 对于A B的每次输入,通过非门都会进行输出,
 真值表就列出了这个元件的所有输入对应输出的情况表
2.一位加法的逻辑设计

首先我们要明确一位加法的逻辑是什么样的

代码语言:javascript
复制
0 + 0 = 0     0 + 1 = 1    0 + 1 = 1     1 + 1 = 0 (超出长度1溢出)
如果将输入A和B看做加数 ,结果看成Y:可以画出下面的真值表:   

--------------------------元件真值表-------------------------
 输入A  输入B   输出Y           
 0      0       0            
 0      1       1            
 1      0       1            
 1      1       0    
 -------------------------------------------------------------
|--而现在需要做的就是如何通过与门和非门的拼接来形成一个元件
|--使得这个真值表成立,你可以验证一下上面的四种情况:
比如 A B 都输入高电压(即1),来校验一下
上面:非A 得 0 ---> 0 与 B 得 1   --->  取非得 0
                                                --->0 与 0 得 0  即输出Y是0
下面:非B 得 0 ---> 0 与 A 得 1   --->  取非得 0
1位加法器
1位加法器
代码语言:javascript
复制
这里简单说一下怎么知道要这样画: 
注:这里为了方便书写,用位运算的符号表述,~ 代表非 &代表与 |代表或

--------------------------元件真值表-------------------------
 输入A  输入B   输出Y           
 0      0       0            
 0      1       1            
 1      0       1            
 1      1       0     
-------------------------------------------------------------
[1].找出Y=1的所有行  
[2].写出上步中的逻辑表达式并用或连接 (~A & B) | ( A & ~B)
[3].通过与和非替换掉或: 替换公式 X|Y = ~(~X & ~Y)
~((~(~A & B)) & (~(A & ~B)))  
[4].根据与非关系自内向外画图:
|---上行:~A 即上面的 非门A,然后和 B 一起进入或门 ,结果再取非 即:~(~A & B) 
|---下行:~B 即下面的 非门B,然后和 A 一起进入或门 ,结果再取非 即:~(A & ~B)
|---上下两行的结果进入或门,之后再入非门 ~((上行结果) & (下行结果))
3.加法器封装

说到这里貌似和封装也搭不上啊?但我已经实现了一个逻辑单元 这个单元可以将两个输入按照1位二进制的逻辑运行,于是封装的价值便体现了 现在将输入的线连起来之后,再套上一个外壳,它便是一个有逻辑价值独立元件

1位加法器
1位加法器
1位加法器
1位加法器
4.进位器逻辑封装

首先我们要明确进位的逻辑是什么样的

代码语言:javascript
复制
逻辑单元:0 + 0 = 0     0 + 1 = 0    1 + 0 = 0     1 + 1 = 1 

--------------------------元件真值表-------------------------         
 输入A  输入B   输出Z           
 0      0       0            
 0      1       0            
 1      0       0            
 1      1       1 
 -------------------------------------------------------------
 
按照上面的步骤来: A & B  发现原来一个与门就能进行进位操作

现在封装的价值就体现了,也就是轮子的价值,可复用, 现在将两个元件进行组装,再加个套子,就能实现更复杂些的逻辑处理单元

加法器
加法器
5.小结

对使用者而言:哥管你里面什么逻辑,我给输入,你给我我想要的输出就行了 确实一个封装体就做到了,隐藏内部的逻辑实现,将最简洁的使用方式告诉使用者 下面的一幅图和上面的封装体能完成相同的功能,你更用哪个?

加法器
加法器
代码语言:javascript
复制
--------------元件真值表------------------         
 输入A  输入B    输出Z   输出Y     
 0      0        0       0       
 0      1        0       1       
 1      0        0       1    
 1      1        1       0       
 
这是将Z,Y两个输出存顺序排列: 0+0=00  0+1=01  1+0=01  1+1=10 
而这个进一位加法器的逻辑单元已经完善了,就可以当做一个元件来使用
 
形象而简洁地描述一下:
 在执行  1 + 1 的时候
 高电平经过A,高电平经过B,通过电子元件的内部逻辑单元CRA输出1,通过ADD输出0,
 即 Z输出 1,Y输出 0 ,按Z Y进行输出的到了结果 10  

为了更形象说明,这里拿一个74HC138N看一下,大概三毛钱一个, 传说中的三八译码器,以前玩单片机做电子钟的时候用到过,现在差不多忘完了...

74HC138
74HC138

在此强调一点:电子元件内部是封装符合真值表的逻辑单元 电子元件都有输入和输出,即输入+ 逻辑单元处理 ----> 希望的输出 至此为止,不再延伸,有兴趣的自己玩...

6. 升华

我们针对输入和输出暴露引脚,将逻辑单元封装其中 这样对于指输入就会有期望的输出,在便是逻辑单元的封装 它在软件领域有一个俗称:轮子,这里暂时称为封装体

封装体的优越之处:(只要封装体能实现预期的功能,那么:) |--无论时间,空间的变化,你的输入都会变成你期望的输出 |--这便具有可复用性,再需要它时便无需再次设计 |--隐藏内部的逻辑实现,以保护封装体的内部封装不被破坏 |--仅暴露接口提供输入和输出,简化使用方式

下面关于封装做一个类比:

--

电子元件

电脑

开源类库

封装物

硬质外壳

塑料/金属外壳

.jar,.so包等

躯壳

接口

引脚

键盘,USB,电源键等

api方法

口 ,耳,眼,鼻,皮肤

输入

高低电平

键盘输入,U盘头

方法调用

食物,音乐,书籍,气味,触摸

输出

运算结果

屏幕显示,U盘信息

运算结果

能量,思想,劳动力,汗液等

处理核心

逻辑单元

CPU

大脑

使用前提

真值表

说明书

API文档

不可描述(宇宙造物手册?)

核心组成元

与门+非们

各种电子元件

属性+方法

脱氧核糖核酸

7.封装没有缺点吗?

我还没发现世上有什么东西没有缺点

就连我们这么伟大的人类都可能发生基因突变,更何况是人类制造的封装体 对于电子元件来说,由于环境因素,人为因素可能导致元件内部的损坏, 而无法拆封的你只能选择更换一个封装体,这就造成了浪费,虽然在我们眼里不算什么 对于一个开源框架来说,一个bug可能导致所有使用者的崩溃,这是很严重的 也就是使用一个封装体是具有一定的风险性的,当然大厂的框架会相对完善 再者就是接口的复杂,有种必须按照别人意志去做的压迫感 没有真值表和接口图,使用的人来说是灾难,这种感觉就像... 必须使用的类库没有API文档,并且方法命名为a(),b(),c()一样让人抓狂 可惜对于人类,宇宙并没有留下一份API文档,一切都要靠我们自己来编写...

好了,引入完成,下面进入正文

二、编程中初遇封装
1.与class的初遇

两年前,一开始class 以及它 的 private 是我非常难理解的 对类的认识是在C++里,印象最深的是圆这个类,从获取圆的面积开始

代码语言:javascript
复制
---->[头文件]-------------------
#ifndef BSAE_CIRCLE_H
#define BSAE_CIRCLE_H
class Circle {
    const double PI = 3.141592654;
public:
    double getArea();
    double getRadius() const;
    void setRadius(double radius);
private:
    double mRadius;
};
#endif //BSAE_CIRCLE_H

---->[cpp文件]-------------------
#include "Circle.h"
double Circle::getArea() {
    return mRadius * mRadius * PI;
}

double Circle::getRadius() const {
    return mRadius;
}

void Circle::setRadius(int radius) {
    mRadius = radius;
}

---->使用类----------------
#include <iostream>
#include "circle/Circle.h"

int main() {
    Circle circle;
    circle.setRadius(10);
    std::cout << circle.getArea() << std::endl;
    return 0;
}
2.现在来看

一个类便是类的设计者对于某种概念的封装 我理解类存在的意义确实费了不少时间,当时疑问: 为什么一行代码解决的事要拆成一个类?而且又是头又是cpp的

现在发现有这种疑问的根源在于当时没有认清自己的角色 认清自己的角色,这对入门的人来说是非常困难的,类的本身就是一个逻辑处理单元 而程序员的角色是设计类的人,就像电子元件的设计者在设计逻辑单元一样 但任何一个程序员都必定是第一个使用者,所以两个角色在同一个人身上 对于入门的来说,只能是一个使用者,因为你只是在意获取结果,而没有程序员的设计之魂 就会感觉很混乱,站在一个使用者的角度,类确实将半径为10的圆面积这个问题变得复杂了

关系
关系

但如果封装的思想到位,就可以明确这个类的价值 setRadius进行输入,getRadius,getArea进行输出,其中的一切都是逻辑单元

内部分析
内部分析

如果你还不清楚,看下图:这就是封装 看不见内部了,该怎么用? 电子元件有真值表,类有API文档 至此我想对于类和封装的关系应该讲的淋漓尽致了

封装
封装
代码语言:javascript
复制
----------Circle API--------------------------
double getArea(); 获取圆的面积
double getRadius(); 获取圆的半径
void setRadius(double radius); 设置圆的半径
-----------------------------------------------

当你在非Circle中使用的时候,你的角色就变成了Circle元件的用户 你需要关注的就只用它的输入和输出,内部逻辑实现已经不需要你考虑了 不过一旦你进入了Circle中,你的角色就是Creator,你可以把自己当成造物主来实现逻辑单元

代码语言:javascript
复制
Circle circle;
circle.setRadius(10);
circle.getArea()//314.159
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.02.16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、与封装的初遇
    • 1.与门(AND)和非门(NOT)
      • 2.一位加法的逻辑设计
        • 3.加法器封装
          • 4.进位器逻辑封装
            • 5.小结
              • 6. 升华
                • 7.封装没有缺点吗?
                • 二、编程中初遇封装
                  • 1.与class的初遇
                    • 2.现在来看
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档