抽象在编程中的应用与挑战

分类: members365sport365 时间: 2025-10-12 20:30:50 作者: admin 阅读: 9238 点赞: 700
抽象在编程中的应用与挑战

抽象是编写代码的基础,有效的认识代码中的抽象,对我们在项目实施中选择设计模式和架构都会有很大的帮助。 据我所知的抽象分为3种:

过程抽象数据抽象控制抽象

过程抽象

过程抽象是最常用的一种抽象,它是消除系统中重复代码头号方法。 例如,在一个App的页面上,当页面打开时,会加载数据;在App重新唤起时,会重新加载数据;当用户点击某个按钮时,会重新加载数据; 面对这种情况,我们通常会把这段代码抽象出来,将其放在一个函数中。

onLoad() {

this.loadData();

}

onShow(){

this.loadData();

}

onBuy(){

...

this.loadData();

}

这样做的好处是当数据加载逻辑有变化时,修改的地方会被限制在loadData函数中,保证了逻辑的一致性。

控制抽象

控制抽象的抽象层次比过程抽象要高,先举一个例子。 在某个场景中,图片和文字都要按照一个优先级逻辑来处理。

const img = (isConfigured(record) && img1) || (isHot(reord) && hotImg) || (isCurrent(record) && currentImg)

const text = (isConfigured(record) && '已配置') || (isHot(reord) && '热销商品') || (isCurrent(record) && '当前商品')

在上面的代码中存在重复的控制逻辑,因此对代码进行重构,得到下面的代码。

const buildPrecedence(record)=>(configHandler, hotHandler, currentHandler)=>(isConfigured(record) && configHandler()) || (isHot(reord) && hotHandler) || (isCurrent(record) && currentHandler())

const precedence = buildPrecedence(record)

const img = precedence(()=>img1, ()=>hotImg, ()=>currentImg)

const text = precedence(()=>'已配置', ()=>'热销商品', ()=>'当前商品')

有趣的是,之前的两行代码变成了现在的四行代码,这也反应出了使用控制抽象的成本。但现在,如果要改变优先级处理逻辑,就只需要修改buildPrecedence。 个人认为,控制抽象更加接近于艺术,是艺术就会有美与丑。做得好的控制抽象,整个代码就利于他人的理解和维护;做得不好的控制抽象,代码可能过了一段时间连自己都要半天才能看懂。 因此,肯定会有大咖不同意上面的重构方式,这也很正常,因为控制抽象本身只是抽象方式的一种归类,而不是具体的实现方法。控制抽象是要去学习和创新的,这是为什么会有23中常用设计模式。

抽象带来的问题

因此,我们在实际的项目代码上可能会遇到2种典型的情况,一种是没有使用任何抽象,代码基本上就是从业务需求直接翻译过来。这种代码的好处是很容易理解,但因为同一条业务逻辑在业务流程中可能多次出现,因此按照这种思路写出来的代码也是多次重复的,因此不好维护,即一旦那条业务逻辑发生改变,就要对代码中对应的多个地方进行修改,而是否能够改完所有的地方全凭当事人的记忆,还有全文搜索的运气。

一种是使用了抽象设计,但这个抽象不够合理。注意,就算使用合理的抽象,当问题发生时,也会通过一层一层的引用去定位问题,这本身就比较麻烦。但如果这个抽象不够合理,这种麻烦的程度会大幅度加深,从而增加代码的维护难度。

我也作为万千程序员中的一员,几乎每天都在经受着抽象带来的考验。

相关推荐