建材秒知道
登录
建材号 > 设计 > 正文

关于软件设计重用的问题 急!!!3小时内要答案

温暖的树叶
欢喜的小馒头
2023-02-17 11:15:04

关于软件设计重用的问题 急!!!3小时内要答案

最佳答案
和谐的外套
背后的彩虹
2026-05-10 22:52:42

如果在软件设计时没有考虑到重用的话,你就要做很大改动,工作量比较大。

比如你用VB写的话,可以把它写成ActiveX部件形式,这样VC也可以重用。但是你以前没这样写,现在接口都需要重新定义。

最新回答
开放的心情
清爽的龙猫
2026-05-10 22:52:42

可以。

1、打开一个wps文档。

2、输入一组数字,这里模拟了任一组数字。

3、选中这组数字,右键点击复制在wps文档的空白处右键点击粘贴。

4、在wps文档的空白处粘贴完成后有两组数字。

5、直接在空白处按键盘上的F4,就可以重复上一步的粘贴操作。

落后的糖豆
传统的雪碧
2026-05-10 22:52:42
在“代码的坏味道”中,代码冗余是其中的一条。而应对代码冗余最基本的方法就是代码重用,并且在面向对象中,重用也是一种基本的思路。

当面向对象设计成为主流时,“重用”曾经被吹捧为面向对象的主要优点之一。为了实现“重用”,教科书总是告诉我们,应该找到已有的东西,用派生类的形式对其进行小幅修改,或加入新的特性,实现代码的“重用”。所以现在一提到面向对象的代码重用,大多数程序员想到的是面向对象的“继承”。真的是这样的吗?我们可以看看下面的一个例子:

现在有一个项目:对动物的不同特征建模。项目的需求如下:

1、 每种动物都有数量不同的腿;

2、 动物对象必须能够记住并获取这一信息;

3、 每种动物的移动方式不同(考虑行走和飞行两种情况);

4、 对于给定的地形类型,动物对象必须能够返回从一个地方移动到另外一个地方所花费的时间。

处理“腿数”这个变化,很简单,也很典型,就是用一个数据成员存放这个值,并且设置该值的读取和赋值方法(在Java中也称为getter/setter方法)。但在处理动物移动方式上,通常有两种方法:第一种是用一个数据成员说明动物对象拥有哪种移动方式(即开关变量,在本文中暂不讨论开关变量的问题);第二种是用两种不同类型的Animal类(都派生自Animal基类),因为Animal的大部分特性是相同的,仅移动方式不同而已,为了代码的重用,用继承来处理不同的部分,如下UML图:

到目前为止,该设计没有暴露出任何问题。但现在,需求发生改变了(这在软件开发是无时无刻不在发生的事情),不仅要考虑动物的移动方式,还有考虑动物的食物属性(肉食动物、草食动物、杂食动物)时,问题就会变得非常的复杂,因为有会飞的肉食动物(老鹰)、有会行走的肉食动物(狮子、老虎)、也有会飞的草食动物(麻雀)、会行走的草食动物(牛),甚至还有行走的杂食动物(乌龟),那么在之前的设计上继续使用继承来实现代码的重用,那么会得到如下的设计UML图:

现在我看发现,子类的数量爆炸性的出现(这里还没有考虑杂食动物的情况),如果继续有动物的特性需要被考虑进来,那么,这个继承关系将会更加复杂,子类数量将巨大,给后期维护带来巨大的麻烦。

采用继承来实现代码重用,它能够这次凑效,但是无法次次凑效。诸如此类的反复特化,要么会使代码变得无法理解,要么产生冗余。特化技术最终会产生太深的继承层次。糟糕的是继承层次太深导致程序难以理解(弱内聚)、存在冗余、难以测试而且多个概念耦合在一起。无怪乎许多人认为面向对象有些言过其实——尤其是这一切都是因为遵循了面向对象“重用”要求。

那么我们真的束手无策吗?《设计模式》的大师们的话仿佛又在耳边回荡:“考虑设计中什么应该是可变的”、“对变化的概念进行封装”,并且最重要的是“优先使用对象聚集(组合),而不是类继承”。大师的话仿佛给了我们很好的提示:寻找设计中的变化,并封装在一个类中;将这个类包含在另外一个类中。

我们还是考虑上面的那个例子。什么是变化的:动物的腿数、动物的行动方式、动物的食物属性,这些是变化的。找到了变化,下一步就是进行封装了,动物的腿数我们已经得到了很好的处理。那么来考虑动物的行动方式和动物的食物属性。可以考验下面的设计:

将动物的行动方式和动物的食物属性分别封装在AnimalMovement和AnimalFood这个两个类中,它们的变化体现在各种的子类中,这样,动物的行动方式和动物的食物属性就不会方法任何的关联(其实它们之间本来就没有关联关系),在Aimal类中,持有AnimalMovement和AimalFood的引用,当AnimalMovement和AimalFood发生变化时,也不会影响到Aimal类。

我们现在再反过头来看看动物的腿数的这个属性,其实这个也是一个变化,好像我们对它进行特殊的处理,但是仔细想想,我们也是将其封装在了int中,只是这是一个数据变量。但是真正的面向对象语言中,万事万物皆对象,甚至内置的数据成员也是对象(如果我们将int换成Integer,或许更容易理解一点)。

其实重用并不是使用面向对象方法的原因。降低维护成本和使代码更加灵活,更容易扩展,才是更重要的考虑因素。使用正确的面向对象技术当然可以实现重用,但并不是通过直接使用该对象,然后由它派生新的变体对其重用即可达到的。这样做的结果是产生难以维护的代码。所以:对象的真正威力并不在于继承,而是来自于封装行为。但我们往往错误的使用前者而忽略了后者。

那么被面向对象“鼓吹”的继承就没有作用吗?其实不是,反而相反,继承拥有很大的作用,没有继承就没有多态,没有多态,那么上面的第二个设计方案也无法实现。继承本身并不是什么特别难的技巧,但是要能够把继承运用的好却是很难的。那么继承该用在什么地方呢?让我们在来聆听一下大师的教诲:在OO的学习中,继承占有很重要的地位,但这并不是说可以到处滥用。相反,运用继承的时候,应该尽可能的保守,只有在它能带来很明显好处的时候,才能使用。在判断该使用合成还是继承的时候,有一个最简单的办法,就是问一下自己,是不是会把子类向上转型为基类。如果必须转型,那么继承就是必须的,如果不是,那么就该看看是不是不该使用继承。

“优先使用对象聚集(组合),而不是类继承”,请永远记住这句话,并将其运用到实际项目中。继承和合成都能让你在已有类的基础上创建新类。但通常情况下,合成是把已有的类当作新类底层实现的一部分来复用,而继承则是复用其接口。尽管面向对象的编程会反复强调继承,但是当你着手设计的时候,通常情况下还是应该先考虑合成,只有在必要的时候才使用继承。合成会更灵活。

参考资料:

《Java编程思想》

《设计模式解析》

《重构——改善现有代码的设计》

《设计模式:可复用面向对象软件的基础》

善良的火车
光亮的冬天
2026-05-10 22:52:42
[编辑本段]设计模式和框架现在,可复用面向对象软件系统现在一般划分为三大类:应用程序工具箱和框架(Framework),我们平时开发的具体软件都是应用程序;Java的API属于工具箱而框架是构成一类特定软件可复用设计的一组相互协作的类。EJB(EnterpriseJavaBeans)是Java应用于企业计算的框架.

框架通常定义了应用体系的整体结构类和对象的关系等等设计参数,以便于具体应用实现者能集中精力于应用本身的特定细节。框架主要记录软件应用中共同的设计决策,框架强调设计复用,因此框架设计中必然要使用设计模式.

另外,设计模式有助于对框架结构的理解,成熟的框架通常使用了多种设计模式,如果你熟悉这些设计模式,毫无疑问,你将迅速掌握框架的结构,我们一般开发者如果突然接触EJBJ2EE等框架,会觉得特别难学,难掌握,那么转而先掌握设计模式,无疑是给了你剖析EJB或J2EE系统的一把利器。

聪慧的蛋挞
隐形的导师
2026-05-10 22:52:42
框架模式和设计模式的区别

框架、设计模式这两个概念总容易被混淆,其实它们之间还是有区别的。框架通常是代码重用,而设计模式是设计重用,架构则介于两者之间,部分代码重用,部分设计重用,有时分析也可重用。在软件生产中有三种级别的重用:内部重用,即在同一应用中能公共使用的抽象块代码重用,即将通用模块组合成库或工具集,以便在多个应用和领域都能使用;应用框架的重用,即为专用领域提供通用的或现成的基础结构,以获得最高级别的重用性。

框架与设计模式虽然相似,但却有着根本的不同。设计模式是对在某种环境中反复出现的问题以及解决该问题的方案的描述,它比框架更抽象;框架可以用代码表示,也能直接执行或复用,而对模式而言只有实例才能用代码表示设计模式是比框架更小的元素,一个框架中往往含有一个或多个设计模式,框架总是针对某一特定应用领域,但同一模式却可适用于各种应用。可以说,框架是软件,而设计模式是软件的知识。

英俊的板栗
标致的店员
2026-05-10 22:52:42

框架(framework)是一个框子——指其约束性,也是一个架子——指其支撑性。是一个基本概念上的结构,用于去解决或者处理复杂的问题。

框架这个广泛的定义使用的十分流行,尤其在软件概念。框架也能用于机械结构。

简介。

框架、设计模式这两个概念总容易被混淆,其实它们之间还是有区别的。构件通常是代码重用,而设计模式是设计重用,框架则介于两者之间,部分代码重用,部分设计重用,有时分析也可重用。

在软件生产中有三种级别的重用:内部重用,即在同一应用中能公共使用的抽象块代码重用,即将通用模块组合成库或工具集,以便在多个应用和领域都能使用;应用框架的重用,即为专用领域提供通用的或现成的基础结构,以获得最高级别的重用性。