代码复用的规则

转:http://5a5g.blog.sohu.com/1756764.html


1、 对接口编程 
"对接口编程"是面向对象设计(OOD)的第一个基本原则。它的含义是:使用接口和同类型的组件通讯, 
即,对于所有完成相同功能的组件,应该抽象出一个接口,它们都实现该接口。具体到JAVA中,可以是接口 
(interface),或者是抽象类(abstract class),所有完成相同功能的组件都实现该接口,或者从该抽 
象类继承。我们的客户代码只应该和该接口通讯,这样,当我们需要用其它组件完成任务时,只需要替换该 
接口的实现,而我们代码的其它部分不需要改变! 

 

当现有的组件不能满足要求时,我们可以创建新的组件,实现该接口,或者,直接对现有的组件进行扩展, 
由子类去完成扩展的功能。 

2、 优先使用对象组合,而不是类继承 
"优先使用对象组合,而不是类继承"是面向对象设计的第二个原则。并不是说继承不重要,而是因为每个学 
习OOP的人都知道OO的基本特性之一就是继承,以至于继承已经被滥用了,而对象组合技术往往被忽视了。 
下面分析继承和组合的优缺点: 

类继承允许你根据其他类的实现来定义一个类的实现。这种通过生成子类的复用通常被称为白箱复用 
(white-box reuse)。术语"白箱"是相对可视性而言:在继承方式中,父类的内部细节对子类可见。 

对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组合对象来获得。对象组合要求对象 
具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse),因为被组合的对象的内部细节是 
不可见的。对象只以"黑箱"的形式出现。 

继承和组合各有优缺点。类继承是在编译时刻静态定义的,且可直接使用,类继承可以较方便地改变父类的 
实现。但是类继承也有一些不足之处。首先,因为继承在编译时刻就定义了,所以无法在运行时刻改变从父 
类继承的实现。更糟的是,父类通常至少定义了子类的部分行为,父类的任何改变都可能影响子类的行为。 
如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了 
灵活性并最终限制了复用性。 

对象组合是通过获得对其他对象的引用而在运行时刻动态定义的。由于组合要求对象具有良好定义的接口, 
而且,对象只能通过接口访问,所以我们并不破坏封装性;只要类型一致,运行时刻还可以用一个对象来替 
代另一个对象;更进一步,因为对象的实现是基于接口写的,所以实现上存在较少的依赖关系。 

优先使用对象组合有助于你保持每个类被封装,并且只集中完成单个任务。这样类和类继承层次会保持较小 
规模,并且不太可能增长为不可控制的庞然大物(这正是滥用继承的后果)。另一方面,基于对象组合的设 
计会有更多的对象(但只有较少的类),且系统的行为将依赖于对象间的关系而不是被定义在某个类中。 

注意:理想情况下,我们不用为获得复用而去创建新的组件,只需要使用对象组合技术,通过组装已有的组 
件就能获得需要的功能。但是事实很少如此,因为可用的组件集合并不丰富。使用继承的复用使得创建新的 
组件要比组装已有的组件来得容易。这样,继承和对象组合常一起使用。然而,正如前面所说,千万不要滥 
用继承而忽视了对象组合技术。 

相关的设计模式有:Bridge、Composite、Decorator、Observer、Strategy等。 

下面的例子演示了这个规则,它的前提是:我们对同一个数据结构,需要以任意的格式输出。 

第一个例子,我们使用基于继承的框架,可以看到,它很难维护和扩展。 
abstract class AbstractExampleDocument 

// skip some code ... 
public void output(Example structure) 

if( null != structure ) 

this.format( structure ); 


protected void format(Example structure); 

 

第二个例子,我们使用基于对象组合技术的框架,每个对象的任务都清楚的分离开来,我们可以替换、扩展 
格式类,而不用考虑其它的任何事情。 
class DefaultExampleDocument 

// skip some code ... 
public void output(Example structure) 

ExampleFormatter formatter = 
(ExampleFormatter) manager.lookup(Roles.FORMATTER); 
if( null != structure ) 

formatter.format(structure); 



这里,用到了类似于"抽象工厂"的组件创建模式,它将组件的创建过程交给manager来完成; 
ExampleFormatter是所有格式的抽象父类; 

3、 将可变的部分和不可变的部分分离 
"将可变的部分和不可变的部分分离"是面向对象设计的第三个原则。如果使用继承的复用技术,我们可以在 
抽象基类中定义好不可变的部分,而由其子类去具体实现可变的部分,不可变的部分不需要重复定义,而且 
便于维护。如果使用对象组合的复用技术,我们可以定义好不可变的部分,而可变的部分可以由不同的组件 
实现,根据需要,在运行时动态配置。这样,我们就有更多的时间关注可变的部分。 

对于对象组合技术而言,每个组件只完成相对较小的功能,相互之间耦合比较松散,复用率较高,通过组 
合,就能获得新的功能。 

4、 减少方法的长度 
通常,我们的方法应该只有尽量少的几行,太长的方法会难以理解,而且,如果方法太长,则应该重新设 
计。对此,可以总结为以下原则: 

三十秒原则: 
如果另一个程序员无法在三十秒之内了解你的函数做了什么(What),如何做(How)以及为什么要这样做 
(Why),那就说明你的代码是难以维护的,必须得到提高; 
一屏原则: 
如果一个函数的代码长度超过一个屏幕,那么或许这个函数太长了,应该拆分成更小的子函数; 
一行代码尽量简短,并且保证一行代码只做一件事 

那种看似技巧性的冗长代码只会增加代码维护的难度。 

5、 消除case / if语句 
要尽量避免在代码中出现判断语句,来测试一个对象是否某个特定类的实例。通常,如果你需要这么做,那 
么,重新设计可能会有所帮助。我在工作中遇到这样的一个问题:我们在使用JAVA做XML解析时,对每个标 
签映射了一个JAVA类,采用SAX(简单的XML接口API:Simple API for XML)模型。结果,代码中反复出现 
了大量的判断语句,来测试当前的标签类型。为此,我们重新设计了DTD(文档类型定义:Document Type 
Definition),为每个标签增加了一个固定的属性:classname,而且重新设计了每个标签映射的JAVA类的 
接口,统一了每个对象的操作: addElement(Element aElement); //增加子元素 
addAttribute(String attName, String attvalue); //增加属性; 

则彻底消除了所有的测试当前的标签类型的判断语句。每个对象通过 Class.forName 
(aElement.attributes.getAttribute("classname")).newInstence(); 动态创建, 

6、 减少参数个数 
有大量参数需要传递的方法,通常很难阅读。我们可以将所有参数封装到一个对象中来完成对象的传递,这 
也有利于错误跟踪。 

许多程序员因为,太多层的对象包装对系统效率有影响。是的,但是,和它带来的好处相比,我们宁愿做包 
装。毕竟,"封装"也是OO的基本特性之一,而且,"每个对象完成尽量少(而且简单)的功能",也是OO的一 
个基本原则。 

7、 类层次的最高层应该是抽象类 
在许多情况下,提供一个抽象基类有利做特性化扩展。由于在抽象基类中,大部分的功能和行为已经定义 
好,使我们更容易理解接口设计者的意图是什么。 

由于JAVA不允许"多继承",从一个抽象基类继承,就无法再从其它基类继承了。所以,提供一个抽象接口 
(interface)是个好主意,一个类可以实现多个接口,从而模拟实现了"多继承",为类的设计提供了更大的 
灵活性。 

8、 尽量减少对变量的直接访问 
对数据的封装原则应该规范化,不要把一个类的属性暴露给其它类,而是应该通过访问方法去保护他们,这 
有利于避免产生波纹效应。如果某个属性的名字改变,你只需要修改它的访问方法,而不是修改所有相关的 
代码。 

9、 子类应该特性化,完成特殊功能 
如果一个子类只是使一个组件变成组件管理器,而不是实现接口功能,或者,重载某个功能,那么,就应该 
使用一个外部的容器类,而不是创建一个子类。 

建议:类层次结构图,不要太深; 

例如:下面的接口定义了组件的功能:发送消息;类Transceiver实现了该接口;而其子类Pool只是管理多 
个Transceiver对象,而没有提供自己的接口实现。建议使用组合方式,而不是继承! 


public interface ITransceiver{ 
public abstract send(String msg); 

public class Transceiver implements ITransceiver { 
public send(String msg){ 
System.out.println(msg); 

//使用继承方式的实现 
public class Pool extends Transceiver{ 
private List pool = new Vector(); 
public void add(Transceiver aTransceiver){ 
pool.add(aTransceiver); 

public Transceiver get(int index){ 
pool.get(index); 

//使用组合方式的实现 
public class Pool { 
private List pool = new Vector(); 
public void add(Transceiver aTransceiver){ 
pool.add(aTransceiver); 

public Transceiver get(int index){ 
pool.get(index); 

 

10、 拆分过大的类 
如果一个类有太多的方法(超过50个),那么它可能要做的工作太多,我们应该试着将它的功能拆分到不同 
的类中,类似于规则四。 

11、 作用截然不同的对象应该拆分 
在构建的过程中,你有时会遇到这样的问题:对同样的数据,有不同的视图。某些属性描述的是数据结构怎 
样生成,而某些属性描述的是数据结构本身。最好将这两个视图拆分到不同的类中,从类名上就可以区分出 
不同视图的作用。 

类的域、方法也应该有同样的考虑! 

12、 尽量减少对参数的隐含传递 
两个方法处理类内部同一个数据(域),并不意味着它们就是对该数据(域)做处理。许多时候,该数据 
(域)应该作为方法的参输入数,而不是直接存取,在工具类的设计中尤其应该注意。例如: 
public class Test{ 
private List pool = new Vector(); 
public void testAdd(String str){ 
pool.add(str); 

public Object testGet(int index){ 
pool.get(index); 

 

两个方法都对List对象pool做了操作,但是,实际上,我们可能只是想对List接口的不同实现Vector、 
ArrayList等做存取测试。所以,代码应该这样写: 
public class Test{ 
private List pool = new Vector(); 
public void testAdd(List pool, String str){ 
pool.add(str); 

public Object testGet(List pool, int index){ 
pool.get(index); 

}

转载于:https://www.cnblogs.com/finered/archive/2012/03/04/2379604.html

内容概要:该论文探讨了一种基于粒子群优化(PSO)的STAR-RIS辅助NOMA无线通信网络优化方法。STAR-RIS作为一种新型可重构智能表面,能同时反射和传输信号,与传统仅能反射的RIS不同。结合NOMA技术,STAR-RIS可以提升覆盖范围、用户容量和频谱效率。针对STAR-RIS元素众多导致获取完整信道状态信息(CSI)开销大的问题,作者提出一种在不依赖完整CSI的情况下,联合优化功率分配、基站波束成形以及STAR-RIS的传输和反射波束成形向量的方法,以最大化总可实现速率并确保每个用户的最低速率要求。仿真结果显示,该方案优于STAR-RIS辅助的OMA系统。 适合人群:具备一定无线通信理论基础、对智能反射面技术和非正交多址接入技术感兴趣的科研人员和工程师。 使用场景及目标:①适用于希望深入了解STAR-RIS与NOMA结合的研究者;②为解决无线通信中频谱资源紧张、提高系统性能提供新的思路和技术手段;③帮助理解PSO算法在无线通信优化问题中的应用。 其他说明:文中提供了详细的Python代码实现,涵盖系统参数设置、信道建模、速率计算、目标函数定义、约束条件设定、主优化函数设计及结果可视化等环节,便于读者理解和复现实验结果。此外,文章还对比了PSO与其他优化算法(如DDPG)的区别,强调了PSO在不需要显式CSI估计方面的优势。
内容概要:本文档详尽介绍了人机交互与网页开发课程作业的复现过程,涵盖内容开发、UI原型设计、网站开发、多保真度原型设计、创意工具和技术应用、网站必备功能实现、学术诚信与提交指南、评分标准等方面。具体包括用户需求分析、低保真和高保真原型设计、前端和后端开发示例、数据库设计、可用性测试、故事板设计、响应式设计、3D交互元素创建、备份工具、管理面板、原创性检查系统、标题页生成器、评分标准检查表、学术写作质量分析器、评分标准映射系统、项目质量保证检查表、低分项目诊断与改进系统、评分标准转换工具以及学术诚信教育模块。每个部分都提供了详细的代码实现和中文解释,确保项目符合课程要求并达到较高的评分标准。 适合人群:适用于正在学习人机交互与网页开发课程的学生,尤其是需要完成类似课程作业的人群;同时也适合希望深入了解Web开发全流程的专业人士。 使用场景及目标:①帮助学生理解并完成课程作业,包括从需求分析到最终提交的全过程;②为开发者提供实际项目开发中的技术参考,如前后端开发、数据库设计、响应式设计等;③确保项目的学术诚信,提供原创性检查和学术写作质量分析工具;④帮助学生理解评分标准,提供详细的评分映射和改进建议;⑤提供学术诚信教育,确保学生了解并遵守学术规范。 其他说明:本文档不仅提供了技术实现的代码示例,还涵盖了项目管理和学术诚信方面的内容,确保学生能够在技术、管理和学术三个方面都能得到全面提升。此外,文档还提供了多种工具和系统,帮助学生更好地准备和优化他们的课程作业,从而获得更高的评分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值