2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 花 3 分钟时间了解技术人应具备的思维能力 - 抽象

花 3 分钟时间了解技术人应具备的思维能力 - 抽象

时间:2022-07-03 22:14:38

相关推荐

花 3 分钟时间了解技术人应具备的思维能力 - 抽象

前言

说到抽象,很多人第一时间想到的就是Java中的抽象类,但你真的足够了解它存在的意义以及使用场景吗?抽象思维算是我们技术人员最重要的思维能力,我们每天都得对需求进行分析、判断及其推理过程,这其中都用到了抽象思维来驱动脑海里生成各种程序运行的画面。在日常工作中,我们不难发现其实占用时间最多的不是敲代码的时间,往往是我们对于需求的梳理以及分析过程占比最大。另外,在review自己曾经写过或小组其它成员的历史代码的时候有没有感到特别陌生且头疼。这其实是一种现状,很多人在编写代码的时候不考虑其健壮性及其可扩展性,并且不愿意添加琐碎的注释。所以这就导致了整个流程变得固化不可外延,也就出现了之前提到的问题。具备抽象能力的工程师往往会最大限度的考虑代码的可扩展性,出现上述问题的概率也就大大降低。今天我们一起来看看抽象能力到底是什么以及它能给我们带来哪些好处。

什么是抽象?

摘取百度百科的一段话

抽象是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征的过程。具体地说,抽象就是人们在实践的基础上,对于丰富的感性材料通过去粗取精、去伪存真、由此及彼、由表及里的加工制作,形成概念、判断、推理等思维形式,以反映事物的本质和规律的方法。

有种在听哲学老师讲课的感觉了

简单来说,抽象就是将一堆东西里相同的部分提取浓缩,舍弃不相同的部分。

如下图所示,它既是房子的立体草图同时也是一幅抽象画。它只包括房子大概的轮廓以及结构,并不参与具体实现,这就是抽象思维。

抽象在程序中的运用

回到文章开头的那个问题,程序中哪体现了抽象呢?Java中的抽象类就是一个例子。

博主专门写了一篇文章介绍四大类的区别以及作用,有兴趣的朋友可以看看~四大类之《普通类、接口类、抽象类、枚举类》_程序桃子的博客-CSDN博客

在Java只有接口类的时候,如果我们要实现一个接口,那就必须得重写它的所有方法。但在有些场景下程序是不必要去重写那么多方法的,下面我举一个例子。

有一个HamburgerFactory,它负责汉堡包的组成部分,不同的Hamburger负责具体的Hamburger出炉。

public interface HamburgerFactory {// 添加面包void addBread();// 添加肉void addMeat();// 添加蔬菜void addVegetables();// 添加沙拉void addSalad();}public class Hamburger implements HamburgerFactory {@Overridepublic void addBread() {System.out.println("添加面包...");}@Overridepublic void addMeat() {System.out.println("添加肉...");}@Overridepublic void addVegetables() {System.out.println("添加蔬菜...");}@Overridepublic void addSalad() {System.out.println("添加沙拉...");}public void show() {addBread();addMeat();addVegetables();addSalad();}}public class NoMeatHamburger implements HamburgerFactory {@Overridepublic void addBread() {System.out.println("添加面包...");}@Overridepublic void addMeat() {}@Overridepublic void addVegetables() {System.out.println("添加蔬菜...");}@Overridepublic void addSalad() {System.out.println("添加沙拉...");}public void show() {addBread();addMeat();addVegetables();addSalad();}}public class NoSaladHamburger implements HamburgerFactory {@Overridepublic void addBread() {System.out.println("添加面包...");}@Overridepublic void addMeat() {System.out.println("添加肉...");}@Overridepublic void addVegetables() {System.out.println("添加蔬菜...");}@Overridepublic void addSalad() {}public void show() {addBread();addMeat();addVegetables();addSalad();}}public class NoVegetablesHamburger implements HamburgerFactory {@Overridepublic void addBread() {System.out.println("添加面包...");}@Overridepublic void addMeat() {System.out.println("添加肉...");}@Overridepublic void addVegetables() {}@Overridepublic void addSalad() {System.out.println("添加沙拉...");}public void show() {addBread();addMeat();addVegetables();addSalad();}}public class Shop {public static void main(String[] args) {// 完整的hamburgerHamburger hamburger = new Hamburger();hamburger.show();System.out.println("hamburger finish...");// 没有肉的hamburgerNoMeatHamburger noMeatHamburger = new NoMeatHamburger();noMeatHamburger.show();System.out.println("noMeatHamburger finish...");// 没有蔬菜的hamburgerNoVegetablesHamburger noVegetablesHamburger = new NoVegetablesHamburger();noVegetablesHamburger.show();System.out.println("noVegetablesHamburger finish...");// 没有salad的hamburgerNoSaladHamburger noSaladHamburger = new NoSaladHamburger();noSaladHamburger.show();System.out.println("noSaladHamburger finish...");}}

运行结果如下:

添加面包...

添加肉...

添加蔬菜...

添加沙拉...

hamburger finish...

添加面包...

添加蔬菜...

添加沙拉...

noMeatHamburger finish...

添加面包...

添加肉...

添加沙拉...

noVegetablesHamburger finish...

添加面包...

添加肉...

添加蔬菜...

noSaladHamburger finish...

啊?你问我为什么没写没有面包的Hamburger,本人确实没见过,也许是我孤陋寡闻了。

完美完成任务!?确实是完成了任务,但是有没有更好的办法呢?答案是有的,一起来看看用抽象类怎么替换接口类吧~

public abstract class AbstractHamburger {// 添加面包protected void addBread(){System.out.println("添加面包...");}// 添加肉protected void addMeat(){System.out.println("添加肉...");}// 添加蔬菜protected void addVegetables(){System.out.println("添加蔬菜...");}// 添加沙拉protected void addSalad() {System.out.println("添加沙拉...");}protected void show() {addBread();addMeat();addVegetables();addSalad();}}public class Hamburger extends AbstractHamburger {}public class NoMeatHamburger extends AbstractHamburger {@Overrideprotected void addMeat() {}}public class NoSaladHamburger extends AbstractHamburger {@Overrideprotected void addSalad() {}}public class NoVegetablesHamburger extends AbstractHamburger {@Overrideprotected void addVegetables() {}}

程序运行结果如下:

添加面包...

添加肉...

添加蔬菜...

添加沙拉...

hamburger finish...

添加面包...

添加蔬菜...

添加沙拉...

noMeatHamburger finish...

添加面包...

添加肉...

添加沙拉...

noVegetablesHamburger finish...

添加面包...

添加肉...

添加蔬菜...

noSaladHamburger finish...

大功告成,是不是比之前代码简洁了很多并且方便扩展。

但其实仍有改进的空间,例如AbstractHamburger可以设计得更加抽象,如果以后需要添加虾仁,那就需要添加一个addShrimp方法,并且在show方法中调用,导致程序可扩展性不强。这个问题就交给在座的各位去完成啦。

程序中处处出现的重复代码

一个很深刻的例子,前几天在我做需求【写bug】的时候,有一段逻辑,伪代码如下。

// RPC方法拿到结果RpcResult rpcResult = rpc.invoke();if (Objects.isNull(rpcResult) && MapUtils.isEmpty(rpcResult.getMap())) {return;}Map<String, Object> map = rpcResult.getMap();if (Objects.nonNull(map.get("str1"))) {// ... }if (Objects.nonNull(map.get("str2"))) {// ... }if (Objects.nonNull(map.get("str3"))) {// ... }// ...

一共判断10多个字段,写得头都大了

后面旁边的同事告诉我,你为什么不抽取成一个函数呢?我恍然大悟,将代码抽取成如下所示:

private boolean isNullForMap(Map<String, Object> map, String str) {return Objects.nonNull(map.get(str));}

if (isNullForMap("str1")) {// ...}if (isNullForMap("str2"))) {// ...}if (isNullForMap("str3"))) {// ...}// ...

是不是看起来舒服多了,它表明上是封装的体现,但实际上体现的是个人抽象思维的能力。如果没有足够的抽象思维,也想不到要包装代码块来封装成函数,那就是我。。。

提升抽象能力三部曲

多阅读:阅读能帮助我们开阔视野,更好的激发创造思维从而提升抽象思维能力。

多总结:及时的总结与沉淀能加深理解,同时提升自己的抽象思维能力。

多练习:充分的重构练习能帮助我们进一步突破瓶颈,提升抽象思维能力。

写在最后

今天的内容到此就结束了,文中如果有写得不是那么准确的地方希望在评论区得到各位大佬的指正与批评。对大家有帮助的话希望多多支持哈~ 下次见

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。