算法设计应该依赖抽象而不是业务

<div class="postBody" id="ace97920-c9e4-432b-8ce4-119fad373fe0" style="border-top-width: 0px; padding-right: 0px; padding-left: 0px; border-left-width: 0px; border-bottom-width: 0px; padding-bottom: 0px; margin: 4px 0px 0px; padding-top: 0px; border-right-width: 0px;">
<p style="text-indent: 21pt;">很多时候,算法的设计是归属于详细设计阶段的。一些公司甚至都没有设计而直接编码。这些往往导致很多算法的实现都混杂在业务模块中。典型的特点是,这些算法会依赖于业务实体的某些属性的实现。</p>
<p style="text-indent: 21pt;">举一个简单的例子,我曾经做过一个项目中,遇到一个排序功能:分部整理。这个排序比我们以往所学的排序不一样,所以很多人都不将它作为算法来看待,而是直接做为业务逻辑功能进行实现。</p>
<ol>
<li>
    <div style="text-indent: 21pt;">排序的基础数据是清单(一个业务实体)的编码</div>
    </li>
    <li>
    <div style="text-indent: 21pt;">排序的依据是清单编码在检索库中的顺序</div>
    </li>
</ol>
<p style="text-indent: 21pt;">如果你细心的话,就会发现,其实上面的两条,和我们的一般排序方法实现起来是一样的!</p>
<ol>
<li>
    <div style="text-indent: 21pt;">比较对象:字符串、整数、浮点数等等</div>
    </li>
    <li>
    <div style="text-indent: 21pt;">比较方法:比较大小、大小写敏感等等</div>
    </li>
</ol>
<p style="text-indent: 21pt;">根据上面的分析,设计这个算法的过程中,应该将清单编码列表作为一个参数传入。注意,这里是是编码列表,而不是实体对象列表。最好的情况是,重新声明一个数组。这样就能将算法和业务实体隔离开。另外,清点编码的检索作为一个排序的比较回调函数。这样,比较的业务也可以和算法分开。最后,<strong>算法其实也不需要实现了</strong>,因为这是通用的。</p>
<p style="text-indent: 21pt;"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/xiammy/267259/o_%e7%ae%97%e6%b3%95%e8%ae%be%e8%ae%a1.png"></p>
<p style="text-indent: 21pt;">大家一定注意到了,上面的设计过程中,一直在强调接口编程。我们的算法如果不依赖于业务,就必须提取出来一个独立的接口。说到接口,我想多说几句,因为很多人在这里有一个误区。</p>
<p style="text-indent: 21pt;">我们在业务代码中,有很多接口。这些接口一般都是业务接口。是因为业务而不得不存在的接口。但是写得多了,很多人可能会将这些和我们所提倡的独立的接口想混淆。让他依赖接口编程,他就直接将业务对象实现的接口引入进来。这种方法的直接后果就是,这部分代码,别的地方不可能再用了!</p>
<p style="text-indent: 21pt;">依赖于业务抽象的算法实现,是有很多好处的:</p>
<ol>
<li style="text-indent: 21pt;">算法简洁、易于阅读 </li>
    <li style="text-indent: 21pt;">层次清楚、易于扩充 </li>
    <li style="text-indent: 21pt;">抽象独立、易于复用</li>
</ol>
<p style="text-indent: 21pt;">对于服用,不光是可以给别人服用,很多时候,就是因为抽象的好,因而可以使用到一些基础算法。复用代码的好处,就是不需要额外的维护啊。</p>
<p style="text-indent: 21pt;">算法设计,是应该高于业务设计的。这样才能体现算法的优势。否则石头一旦沉入大海,我们再也不能看清楚他们了。</p>
</div>

你可能感兴趣的:(算法)