程式設計三次法則

程式設計中的三次法則是代碼重構的一條經驗法則,涉及到當代碼片段出現重複時,如何決定是否用一個新的子程式替代之的標準。

基本介紹

  • 中文名:程式設計三次法則
  • 外文名:Three rules of programming
  • 所屬學科代碼重構
  • 概述代碼重構的一條經驗法則
  • 學科:計算機科學
簡介,原理,C++編程中的三次法則,C/C++ 原始碼三次法則示例,頭檔案header.h,主函式main.cpp,頭檔案實現 header.cpp,

簡介

程式設計中的三次法則(Three rules of programming)是代碼重構的一條經驗法則,涉及到當代碼片段出現重複時,如何決定是否用一個新的子程式替代之的標準。
三次法則的要求是:
允許按需直接複製貼上代碼一次,但如果相同的代碼片段重複出現三次以上的時候,將其提取出來做成一個子程式就勢在必行。
馬丁·福勒在《重構》一書中介紹了三次法則,並認為這一法則是Don Roberts所提出。

原理

在編程中,由於會提高代碼維護的難度,直接複製代碼段的習慣並不好;具體來說,當有代碼片段需要變更時,代碼維護者就必須找出程式中所有與之相同的代碼片段,並都進行修改,但這一過程易出差錯,而且也常會帶來許多麻煩。相對的,如果代碼只在一個地方出現,修改起來就容易多了。
這一法則在代碼量(即行數)較少(甚至只有一行)的時候還有另一種形式的套用,例如:如果你想調用一個函式,並在調用失敗的時候再嘗試調用一次,那使用兩處調用亦可;但若你想在放棄嘗試前至少嘗試5次(注意,這裡的5匹配>=3的要求),那就應該將其寫成循環形式,使代碼中只有一個調用位置。

C++編程中的三次法則

三次法則C++里,它是一個以設計的基本原則而制定的定律。它的要求是,假如有明顯定義下列其中一個成員函式,那么程式設計師必須寫入其他兩個成員函式到類內,也就是說下列三個成員函式缺一不可。
上述三個函式是特別的成員函式,假如程式設計師沒有自行定義或宣告這三個函式,編譯器會自動地創建他們並且編譯到應用程式內。然而,如果程式設計師僅定義其中一個,其餘兩個函式仍然會由編譯器自動產生,這種混雜的情況非常容易產生程式設計師難以預期的錯誤。三法則的存在,正是提醒程式設計師避免那樣的陷阱。

C/C++ 原始碼三次法則示例

頭檔案header.h

#ifndef _HEADER_H_
#define _HEADER_H_
//
// 判斷是否為微軟編譯器
#ifndef _MSC_VER#undef NULL
#define NULL 0
#endif
//
#include <iostream>
#include <limits>
//
using std::cin;
using std::cout;
using std::endl;
//
// 類別:方塊
class CCube
{
public: // 建構子 CCube(); // 含有參數的建構子 CCube(double length, double width, double height); // 三法則:解構子 ~CCube(); // 三法則:複製建構子 CCube(const CCube &sample); // 三法則:設定運運算元 CCube& operator=(const CCube &sample); // 設定長寬高  void setLength(double length);  void setWidth(double width);  void setHeight(double height); // 取得長寬高 double getLength() const; double getWidth() const; double getHeight() const; // 計算體積 double getVolume() const;protected:private: // 長寬高 double m_Length; double m_Width; double m_Height;};
//
void PAUSE(void);
//
#endif

主函式main.cpp

#include"header.h"
//
// 判斷是否為微軟編譯器
#ifndef _MSC_VER
int
#else
void
#endif
main(int argc, char* argv[]){ // 方塊零 CCube cube0(4.3, 5.2, 6.1); // 第一個方塊 { cout << "=== No.1 cube ===" << endl; CCube cube1 = cube0; cout << "Volume of cube = " << cube1.getVolume() << endl; } // 第二個方塊 { cout << "=== No.2 cube ===" << endl; CCube cube2; cube2 = cube0; cout << "Volume of cube = " << cube2.getVolume() << endl; } PAUSE(); return
#ifndef _MSC_VER EXIT_SUCCESS
#endif ;
}

頭檔案實現 header.cpp

#include "header.h"
//
void PAUSE(void){ cin.clear(); cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); cout << "press any key to continue..."; cin.get();}CCube::CCube(){ cout << "Constructor: CCube()" << endl; this->m_Length = 0.0; this->m_Width = 0.0; this->m_Height = 0.0;}CCube::CCube(double length, double width, double height){ cout << "Constructor: CCube(length, width, height)" << endl; this->m_Length = length; this->m_Width = width; this->m_Height = height;}CCube::~CCube(){ cout << "Destructor: ~CCube()" << endl; this->m_Length = 0.0; this->m_Width = 0.0; this->m_Height = 0.0;}CCube::CCube(const CCube &sample){ cout << "Copy constructor: CCube(const CCube &sample)" << endl; // // 保護:禁止設值給自己 if (this != &sample) { this->m_Length = sample.m_Length; this->m_Width = sample.m_Width; this->m_Height = sample.m_Height; }}CCube& CCube::operator=(const CCube &sample){ cout << "Assignment operator: operator=(const CCube &sample)" << endl; // // 保護:禁止設值給自己 if (this != &sample) { this->m_Length = sample.m_Length; this->m_Width = sample.m_Width; this->m_Height = sample.m_Height; } return *this;}double CCube::getVolume() const{ return (this->m_Length * this->m_Width * this-
>m_Height);
}

相關詞條

熱門詞條

聯絡我們