从类,API,框架三个层面学习如何设计可复用软件实体的具体技术学习心得

为什么要复用?

我喜欢从为什么,是什么,怎么做来学习。
自我体会,是为了更加快速,方便的进行开发,例如登陆功能,账号,密码,验证码,基本没有什么改动的地方,如果你以前写过,将他模块化,下一次再遇到同样的需求就可以直接复制粘贴,从搬砖到用手推车搬砖。

复用的级别

(1)代码的复用
包括目标代码和源代码的复用。其中目标代码的复用级别最低,历史也最久,当前大部分编程语言的运行支持系统都提供了连接(Link)、绑定(Binding)等功能来支持这种复用。

(2)设计的复用
设计结果比源程序的抽象级别更高,因此它的复用受实现环境的影响较少,从而使可复用构件被复用的机会更多,并且所需的修改更少。这种复用有三种途径,第一种途径是从现有系统的设计结果中提取一些可复用的设计构件,并把这些构件应用于新系统的设计;第二种途径是把一个现有系统的全部设计文档在新的软硬件平台上重新实现,也就是把一个设计运用于多个具体的实现;第三种途径是独立于任何具体的应用,有计划地开发一些可复用的设计构件。

(3)分析的复用
这是比设计结果更高级别的复用,可复用的分析构件是针对问题域的某些事物或某些问题的抽象程度更高的解法,受设计技术及实现条件的影响很少,所以可复用的机会更大。复用的途径也有三种,即从现有系统的分析结果中提取可复用构件用于新系统的分析;用一份完整的分析文档作输入产生针对不同软硬件平台和其它实现条件的多项设计;独立于具体应用,专门开发一些可复用的分析构件。

(4)测试信息的复用
主要包括测试用例的复用和测试过程信息的复用。

类的层面

  • 继承:
    面向对象的开发语言中自然少不了继承,有了继承,就可以使子类拥有父类的属性和方法,这也是一种复用,甚至可以说是十分重要的一种复用,子类可以不用将某些方法
  • 委托
    在java中类直接调用这个类的static方法,类似c语言中的函数,直接调用就行,这样也是一种类的复用。类似Math.sprt()这种方法。

API层面

API应该做一件事,且做得很好

API应该尽可能小,但不能太小

Implementation不应该影响API

类的设计:尽量减少可变性,遵循LSP原则

方法的设计:不要让客户做任何模块可以做的事情,及时报错

LPS原则

定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。

定义2:所有引用基类的地方必须能透明地使用其子类的对象。

问题由来:
有一功能P1,由类A完成。现需要将功能P1进行扩展,扩展后 的功 能为P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障。

解决方案:
当使用继承时,遵循里氏替换原则。类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法

LSP依赖于以下限制:
前置条件不能强化
后置条件不能弱化
不变量要保持
子类型方法参数:逆变
子类型方法的返回值:协变
异常类型:协变

框架层面

框架:一组具体类、抽象类、及其之间的连接关系
开发者根据 framework的规约,填充自己的代码进去,形成完整系统。通常通过选择性覆盖来扩展框架;或者程序员可以添加专门的用户代码来提供特定的功能—即定义继承了抽象类祖先操作的具体类 Hook方法,它被应用程序覆盖以扩展框架。Hook方法系统地将应用程序域的接口和行为与应用程序在特定上下文中所需的变体解耦。 控制反转:与库或标准用户应用程序不同,控制流不是由调用者决定的,而是由框架决定的。不可修改的框架代码:在接受用户实现的扩展时,框架代码不应该被修改。换句话说,用户可以扩展框架,但不应修改其代码。
常见的框架类似于spring框架这种,spring框架代码不能修改但是拥有DI,IOC,方便用户创建对象,何时创建对象,交给系统来判断,用户只需要使用对象就行了。
类型也有两种:
白盒复用:源代码可见,可修改和扩展,复制已有代码当正在开发的系统,进行修改
优点:可定制化程度高
缺点: 对其修改增加了软件的复杂度,且需要对其内部充分的了解
黑盒复用:源代码不可见,不能修改,只能通过API接口来使用,无法修改代码
优点:简单清晰
缺点:适应性差

你可能感兴趣的:(作业)