Hard Code Logic -> Static Type -> Dynamic Type Data

Hard Code Logic -> Static Type -> Dynamic Type Data

在一篇介绍Design Pattern的文章中,我写过这样的看法:Design Pattern的目标就是分离代码中的 变化部分 和 不变部分,我们尽量把 变化部分 单独抽取出来,以便达到 不变部分 的 最大限度的重用。
最大限度的重用,也是软件开发技术追求的目标。

下面通过一个典型的例子,来分析软件开发技术在这个方向上的发展。
假设我们有这样一段代码:

do a lot of things before…

switch ( type ){
case A:
do something.
case B:
do something;
case C:
do something;
}

do a lot of things after…

我们看到, 这里的逻辑分支是硬编码的(The logic branches are hard coded.)
这意味着,每增加一个type, 就要增加一个硬编码的逻辑分支。
这也意味着,这段代码永远没有办法成为一个可以扩展的公用函数库,达到更好的重用。每次增加type,只能在源代码级别上进行扩展。我们一旦把这段代码的编译结果,打包起来成为公用函数库,这段代码就失去了任何扩展性。

解决这个问题的第一个手法是OO多态。
do a lot of things before…
instance.doSomething();
do a lot of things after…

这里的instance是一个interface,具体的实现类从外部注入进来。我们可以传入A, B, C等实现类,这样就实现了上面的switch(type) 的 case A, case B, case C。同样,我们可以传入D,E,F等实现。实现switch(type) 的 case D, case E, case F。这样就达到了逻辑分支的可扩展性。
这种OO多态手法的核心思路是把代码中的逻辑分支 类型化,把变化点分离出来;通过不同的类型实现,就可以实现不同的变化点逻辑。

某些情况下,人们还有更灵活的需求。那么引入了第二种手法,动态解释。
do a lot of things before…
invokeService( serviceScript );
do a lot of things after…

这个里面的serviceScript可以看作一个字符串。
有可能是这样的一条简单调用语句:”serviceA.doSomething()”.
也有可能是完整一段script: “{this.a = getServiceA(); a.doSomething(); a.doMore();}”

动态解释手法,非常灵活强大。一点不利的情况是,只有运行起来的时候,才知道serviceScript里面是否把 a.doSomething() 错误的写成 a.doesSomething()。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
if (ptr != pd->usb_psy || evt != PSY_EVENT_PROP_CHANGED) return 0; ret = power_supply_get_property(pd->usb_psy, POWER_SUPPLY_PROP_TYPEC_MODE, &val); if (ret) { usbpd_err(&pd->dev, "Unable to read USB TYPEC_MODE: %d\n", ret); return ret; } typec_mode = val.intval; ret = power_supply_get_property(pd->usb_psy, POWER_SUPPLY_PROP_PE_START, &val); if (ret) { usbpd_err(&pd->dev, "Unable to read USB PROP_PE_START: %d\n", ret); return ret; } /* Don't proceed if PE_START=0; start USB directly if needed */ if (!val.intval && !pd->pd_connected && typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { ret = power_supply_get_property(pd->usb_psy, POWER_SUPPLY_PROP_REAL_TYPE, &val); if (ret) { usbpd_err(&pd->dev, "Unable to read USB TYPE: %d\n", ret); return ret; } if (val.intval == POWER_SUPPLY_TYPE_USB || val.intval == POWER_SUPPLY_TYPE_USB_CDP || val.intval == POWER_SUPPLY_TYPE_USB_FLOAT) { usbpd_dbg(&pd->dev, "typec mode:%d type:%d\n", typec_mode, val.intval); pd->typec_mode = typec_mode; queue_work(pd->wq, &pd->start_periph_work); printk("psy_change:start_periph_work\n");/////////////////////////////////////////////////////////////// } return 0; } ret = power_supply_get_property(pd->usb_psy, POWER_SUPPLY_PROP_PRESENT, &val); if (ret) { usbpd_err(&pd->dev, "Unable to read USB PRESENT: %d\n", ret); return ret; } pd->vbus_present = val.intval; /* * For sink hard reset, state machine needs to know when VBUS changes * - when in PE_SNK_TRANSITION_TO_DEFAULT, notify when VBUS falls * - when in PE_SNK_DISCOVERY, notify when VBUS rises */ if (typec_mode && ((!pd->vbus_present && pd->current_state == PE_SNK_TRANSITION_TO_DEFAULT) || (pd->vbus_present && pd->current_state == PE_SNK_DISCOVERY))) { usbpd_dbg(&pd->dev, "hard reset: typec mode:%d present:%d\n", typec_mode, pd->vbus_present); pd->typec_mode = typec_mode; if (!work_busy(&pd->sm_work)) kick_sm(pd, 0); else usbpd_dbg(&pd->dev, "usbpd_sm already running\n"); return 0; } if (pd->typec_mode == typec_mode) return 0; pd->typec_mode = typec_mode; usbpd_dbg(&pd->dev, "typec mode:%d present:%d orientation:%d\n", typec_mode, pd->vbus_present, usbpd_get_plug_orientation(pd));代码分析
06-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值