代码的味道 (转)

代码的味道 (转)[@more@] 代码的味道(转贴之UMLCHINA,讲述在什么情况下进行refactoring)
  (说明,这是erptao.org,refactoring论坛中关于Code Smell的一个贴子,以后我会把相关内容继续转贴到这里)
什么时候需要Refactoring?
代码的味道是高水平 程序员对“好程序“的一种感觉,他们具备一种能力,即使不涉及程序代码的具体实现就能看出你的设计是否合理。
如果代码有“异味“,那么你需要进行Refactorying.

1.重复代码(Duplicate Code)
即使是一两句代码的重复也需要refactoring,有时候重复不是那么明显,你需要首先进行其他的refactoring才能看到代码重复。排除代码重复是OO 软件工程最重要的研究课题之一
2.长方法(Long Method)
来自于面向过程的思路,即使能够在一页内能够显示的方法也可能太长。
3.大类(Large Class)
一个类含有太多的责任和行为
4.参数太多(Long Parameter List)
对象含有状态,不再需要太多的参数。
5.不一致的变化(Divergent Change)
不要把变化速度不同的东西放在一起。不要把一个方法对每个子类的变化的部分和不变化的部分放在一起。不要把对象中每秒都在变化的实例变量和一个月才变化一次的势力变量放在一起...等等。
6.Shotgun Surgery
改变影响到太多的类和方法
7.特性羡慕(Feature Envy)
对其他对象中的数据太感兴趣了
8.数据从(Data Clumps )
一块数据到处一起使用,他们应该有自己的类
9.原始类型困扰(Primitive Obsession)
用类代替原始数据类型
10.开关语句(Switch Statement)
面向对象由其他办法来处理这些依赖于类型的方法。
11.并行继承层次(Parallel Inheritance Hierarchies )
有时候有用但有时候不必要
12.惰类(Lazy Class)
不足以自己成为一个类,应该排除
13.投机通则(Speculative Generality )
不要太多考虑为将来而建立的灵活性
14.消息链(Message Chain )
硬性把客户和导航结构相耦合
15.中间人(Middle Man )
如果他所有的事情就是在做分派,那么应当删除。
16.不合适的亲密(Inappropriate Intimacy)
限制对其他类内部结构的知识和了解。
17.不完整的库类(Incomplete Library Class )
某些时候必须扩展一增加所需的功能
18.数据类(Data Class )
应当添加任务和行为来处理它的数据
19.被拒绝的遗产(Refused Bequest )
子类很少利用父类给予它们的东西
20.注释(Comments )
注释是说明why而不是what的好地方。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-991106/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-991106/

<think>好的,用户想了解C++代码中常见的坏味道及重构方法。首先,我需要回忆一下常见的代码味道,比如过长的函数、过大的类、重复代码等等。然后结合用户提供的引用内容,特别是引用[2]和[3],里面提到了函数过大和临时变量的问题。 用户给的引用里提到过大的函数和类,临时变量被多次赋值,这些在C++中同样存在。比如,过长的函数可以通过提取方法来解决,临时变量多次赋值可以拆分成不同的变量。另外,可能还有其他的坏味道,比如冗余代码、过长的参数列表、数据泥团等。 接下来,我需要将这些坏味道分类,并给出具体的例子和重构方法。例如,过长的函数对应的重构方法是Extract Method,临时变量问题用Split Temporary Variable。用户提供的引用中有具体的例子,比如引用[3]中的重构示例,可以借鉴到C++中。 还需要考虑C++特有的问题,比如指针管理不当、资源泄露、过多的预处理器宏等。这些是否属于坏味道?比如未正确释放内存可能导致内存泄漏,应该使用RAII或者智能指针来改进。 此外,引用[4]提到提炼超类,这在C++中可以通过继承来实现,消除重复代码。例如,如果有多个类有相同的字段和行为,可以创建一个基类来集中这些共同点。 需要注意的是,用户可能不仅想知道坏味道有哪些,还想知道具体的解决方法,所以每个坏味道都需要对应的重构策略。同时,要确保例子用C++代码,而不是其他语言,比如Python的例子可能需要换。 最后,生成相关问题,可能需要围绕重构方法、具体案例、性能影响等方面提问。确保问题与内容相关,帮助用户进一步学习。</think>### C++代码常见坏味道及重构方法 #### 1. 过长函数(Long Method) **现象**:函数包含过多逻辑,代码行数过长(如超过50行),存在大量临时变量或嵌套条件判断[^2]。 **重构方法**: - **提取函数(Extract Method)**:将可复用的代码块封装为独立函数。 - **替换临时变量为查询(Replace Temp with Query)**:减少临时变量依赖。 **示例**: ```cpp // 重构前 void processOrder(Order& order) { double tax = order.price * 0.1; double discount = order.price * 0.05; order.total = order.price + tax - discount; // ...其他20行代码... } // 重构后 double calculateTax(double price) { return price * 0.1; } double calculateDiscount(double price) { return price * 0.05; } void processOrder(Order& order) { order.total = order.price + calculateTax(order.price) - calculateDiscount(order.price); // ...其他逻辑... } ``` --- #### 2. 重复代码(Duplicated Code) **现象**:相同或相似的代码片段在多处重复出现。 **重构方法**: - **提取公共函数(Extract Function)**:将重复代码合并为单一函数。 - **模板方法模式(Template Method Pattern)**:通过继承消除重复逻辑[^4]。 **示例**: ```cpp // 重构前 void printReportA() { // 生成报表A的10行代码... saveToFile("reportA.txt"); } void printReportB() { // 生成报表B的10行代码... saveToFile("reportB.txt"); } // 重构后 void generateReport(const std::string& filename, std::function<void()> generateContent) { generateContent(); saveToFile(filename); } ``` --- #### 3. 过大的类(Large Class) **现象**:类承担过多职责,包含大量成员变量或方法[^2]。 **重构方法**: - **拆分类(Split Class)**:按职责分离为多个小类。 - **提炼超类(Extract Superclass)**:抽取公共部分到基类。 **示例**: ```cpp // 重构前 class Employee { std::string name; double salary; void calculatePay() { /* ... */ } void generateReport() { /* ... */ } // 职责混杂 }; // 重构后 class Party { // 公共基类 std::string name; public: Party(const std::string& name) : name(name) {} }; class Employee : public Party { double salary; void calculatePay() { /* ... */ } }; class ReportGenerator { // 独立职责 void generateReport(const Party& party) { /* ... */ } }; ``` --- #### 4. 冗余临时变量(Split Temporary Variable) **现象**:同一临时变量被多次赋值不同含义的值[^3]。 **重构方法**: - **拆分临时变量(Split Temporary Variable)**:为每个用途创建独立变量。 **示例**: ```cpp // 重构前 double temp = 2 * (height + width); // 周长 std::cout << temp; temp = height * width; // 面积(语义冲突) std::cout << temp; // 重构后 double perimeter = 2 * (height + width); double area = height * width; std::cout << perimeter << area; ``` --- #### 5. 过长参数列表(Long Parameter List) **现象**:函数参数超过3个,难以维护。 **重构方法**: - **引入参数对象(Introduce Parameter Object)**:将相关参数封装为结构体。 **示例**: ```cpp // 重构前 void drawRect(int x1, int y1, int x2, int y2, Color color, int thickness); // 重构后 struct Point { int x, y; }; struct LineStyle { Color color; int thickness; }; void drawRect(Point topLeft, Point bottomRight, LineStyle style); ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值