由DIY想到的面向對象思想


     昨天,我把家里的主機清理了一下,那個臟啊,上次清理還是一年前,機箱里的灰塵可都夠做一桌菜了,呵呵。我把CPU、內存條、顯卡等都拔了下來挨個清理,可是費了好大功夫。我是一個DIY愛好者,在清理過程中不時感覺到自己攢一台機器真的很方便,可以按照自己的需求去購買配件,然后把他們組裝到一起就行了,以后想要升級某個配件只需要將那個配件換掉就行了,而不需要去換整台電腦。想到這里時,突然發現這其中體現了好多面向對象的編程思想。

     想想,我們是如何組裝電腦的,一塊主板,上面有很多各種不同的插槽,可以插CPU、內存條等等,但主板廠商並沒有把CPU和內存條直接焊接在上面,而是留出了不同設備的接口,因而各個模塊被清晰的分開,各司其職,互不影響。主板廠商不需要知道CPU的內部是如何設計的,當然這屬於商業機密,主板的設計與CPU的設計都屬於機密,因而都被封裝了。之所以CPU條能插在主板上使用是因為他們都遵循了統一的行業標准,這樣,主板在設計的時候才能擺脫具體的某個CPU,只要遵從這個CPU的接口標准去設計就可以了,凡是滿足這種接口標准的CPU都可以插在主板上使用。說到這里大家是不是想到了依賴倒置,沒錯,高層模塊不依賴於底層模塊,他們都應該依賴於抽象,讓所有依賴都終止於抽象不正是這些電腦配件的設計思路嗎。同樣,內存廠商與硬盤廠商互相也不需要知道他們的產品內部是如何設計的,他們只知道主板已經為他們留好了接口,他們也按照這種接口標准去設計就可以了,設計組件化同樣也是降低軟件系統復雜度的一種方法,這里也體現了依賴注入的思想。這樣的設計還有有很多優點,首先,這給用戶提供了更靈活的組裝方式,只要是滿足統一接口的設備可以隨便換,例如我現在的CPU是奔騰G620,但現在我覺得玩游戲時G620有些力不從心,我就可以將G620換成Corei3或者是Corei5。第二,當某個設備出現問題時只需要更換壞掉的設備就可以了,而對其他設備沒有任何影響。

    好了,說了這么多白話,要是不寫一個例子出來就太對不起大家了。

    既然設計已經模塊化了,我們就分模塊挨個設計好了,首先從CPU入手。我在上面說了,設計時應該拜托具體的影響,針對抽象編程,那我們就建一個抽象的CPU接口ICpu,代碼如下:

View Code
 public interface ICpu

{

#region --Properties--

/// <summary>

/// 獲取CPU名稱

/// </summary>

string Name

{

get;

}



/// <summary>

/// 獲取主頻

/// </summary>

float Speed

{

get;

}



/// <summary>

/// 獲取外頻

/// </summary>

float ExClock

{

get;

}



/// <summary>

/// 獲取針腳數量

/// </summary>

int PinNumber

{

get;

}

#endregion



#region --Methods--

/// <summary>

/// 運行

/// </summary>

void Run();



/// <summary>

/// 計算

/// </summary>

void Compute();

#endregion

}

 

     在這個CPU接口中我定義了四個主要屬性以及兩個方法。寫到這里,我想到現實生活中的家用CPU市場一直被Inter和AMD壟斷,而Inter與AMD的CPU的接口標准是不同的,甚至同一廠商的CPU也有不同的接口標准,例如Inter有LGA775接口和LGA1155接口等等。因此需要將抽象細化,在這里我們再建一個ILGA1155接口,繼承自ICpu,這個ILGA1155就是我們所說行業標准。

     設計完CPU的抽象之后,我們再來看看內存條如何抽象。內存條可能是大家更換最頻繁的一個配件了,從以前的標配DDR 256M到現在的DDR3 4G,內存的更新換代速度真是很快。裝過機的朋友應該知道一代、二代和三代內存之間是不能互相通用的,DDR的插槽與DDR2、DDR3都不同,雖然DDR2與DDR3的插槽相同但DDR3的工作電壓更低。因此我們在設計時就應該分開考慮,找出他們的相同點與不同點,無論DDR還是DDR2或是DDR3他們的插槽都叫做DIMM,先建一個IDIMM接口,但在實際使用時,又需要分為DDR、DDR2和DDR3三種接口標准,我們就以時下最主流的DDR3為例,建一個IDDR3接口繼承自IDIMM。代碼如下:

View Code
    /// <summary>
/// DIMM接口
/// </summary>
public interface IDIMM
{
#region --Properties--
/// <summary>
/// 獲取內存名稱
/// </summary>
string Name
{
get;
}

/// <summary>
/// 獲取時鍾頻率
/// </summary>
string Speed
{
get;
}

/// <summary>
/// 獲取容量
/// </summary>
string Volume
{
get;
}
#endregion

#region --Methods--
/// <summary>
/// 運行
/// </summary>
void Run();

/// <summary>
/// 停止
/// </summary>
void Stop();
#endregion
}

/// <summary>
/// DDR3內存接口
/// </summary>
public interface IDDR3 : IDIMM
{}

     這個IDDR3也可以理解為當前DDR3內存的行業標准。

     內存設計好了之后,我們再來看看硬盤的抽象如何設計。硬盤抽象的設計比較容易,熟悉硬盤的朋友都知道現在的硬盤接口都是SATA,當然可能還有些人的硬盤還停留在IDE的時代,過時的產品我們就不考慮了。SATA的發展速度也挺快,目前已經發展到SATA3了,不過還好,充滿智慧的人類讓高版本接口都能向下兼容,降低了不少更新換代的成本,在這里SATA的版本問題就不是我們討論的重點了,因此我們只設計一個ISATA接口,作為硬盤產品的接口標准。代碼如下:

View Code
    /// <summary>
/// SATA接口
/// </summary>
public interface ISATA
{
#region --Properties--
/// <summary>
/// 獲取硬盤容量
/// </summary>
string Size
{
get;
}

/// <summary>
/// 獲取硬盤名稱
/// </summary>
string Name
{
get;
}

/// <summary>
/// 獲取傳輸速度
/// </summary>
string Speed
{
get;
}
#endregion

#region --Methods--
/// <summary>
/// 運行
/// </summary>
void Run();

/// <summary>
/// 停止
/// </summary>
void Stop();

/// <summary>
/// 發送數據
/// </summary>
void Send();

/// <summary>
/// 接收數據
/// </summary>
void Receive();
#endregion
}

     這里我只寫了幾個比較有代表性的屬性和方法,僅供參考。

     現在,硬盤也抽象完了,看看還缺什么,對了,主板上還有一個插槽是必不可少的,無論哪一種主板都會帶,通常是乳白色的,大家想到了嗎,沒錯,是PCI接口。PCI接口用處真是很多,可以插聲卡、網卡、電視卡等等。但現在聲卡與網卡大多集成在主板上,PCI插槽已經很少有人去用了,但說到PCI家族的另一個接口大家一定不會陌生,呵呵,當然是PCI-E,這可是當前顯卡的專用插槽,游戲玩家怎么能不知道。好了,我們來琢磨琢磨PCI以及PCI-E應如何抽象,PCI-E應該說是PCI接口的繼承和發展,特別是在傳輸速度上PCI-E提高了不少,因此我們先建一個IPCI接口,然后在建一個IPCIExpress接口繼承自IPCI,代碼如下:

View Code
    /// <summary>
/// PCI接口
/// </summary>
public interface IPCI
{
#region --Properties--
/// <summary>
/// 獲取PCI設備名稱
/// </summary>
string Name
{
get;
}
#endregion

#region --Methods--
/// <summary>
/// 運行
/// </summary>
void Run();

/// <summary>
/// 停止
/// </summary>
void Stop();
#endregion
}

/// <summary>
/// PCI-E接口
/// </summary>
public interface IPCIExpress : IPCI
{
#region --Properties--
/// <summary>
/// 獲取顯示芯片名稱
/// </summary>
string GPUName
{
get;
}

/// <summary>
/// 獲取顯存類型
/// </summary>
string MemoryType
{
get;
}

/// <summary>
/// 獲取顯存容量
/// </summary>
string MemorySize
{
get;
}

/// <summary>
/// 獲取顯存位寬
/// </summary>
int BitWidth
{
get;
}

/// <summary>
/// 獲取顯存頻率
/// </summary>
string MemoryClock
{
get;
}

/// <summary>
/// 獲取核心頻率
/// </summary>
string CoreClock
{
get;
}
#endregion
}

     IPCI接口里我只寫了一個設備名稱屬性,其實還有很多,我只是一時沒有想到,大家懂的就好。

     現在幾個核心部件的設計都完成了,另外還有其他的一些接口沒有設計像PS2,USB,VGA等等,由於時間緊迫我在這就不詳細寫了。呦,差點忘了,寫了這么多,差點把主板給忘了。Well,讓我們把主板抽象設計一下,設計完以上接口標准,主板的設計似乎就很清晰了,當然是把這些接口都嵌在主板上嘍。這里我們又需要考慮到一個問題,就是主板芯片組。在選購主板時會常說用AMD平台還是Inter平台,這句話換一種方式說就是用AMD的CPU還是Inter的CPU。沒錯,主板芯片組就是主板名稱的代號,不同的芯片組支持的CPU是不同的。AMD芯片組的主板只支持AMD的CPU,Inter芯片組的主板只支持Inter的CPU,因此我們在設計時就應該分開考慮。首先新建一個IMainboard接口作為所有主板的抽象,然后我們再選用當前Inter主流的H61芯片組主板作為例子,建一個IH61接口繼承自IMainboard,在H61主板上我們就需要把設計好的接口嵌在上面,代碼如下:

View Code
    /// <summary>
/// 主板抽象
/// </summary>
public interface IMainboard
{
#region --Properties--
/// <summary>
/// 獲取主板名稱
/// </summary>
string Name
{
get;
}
#endregion

#region --Methods--
/// <summary>
/// 運行
/// </summary>
string Run();

/// <summary>
/// 停止
/// </summary>
void Stop();
#endregion
}

/// <summary>
/// H61主板
/// </summary>
public interface IH61 : IMainboard
{
/// <summary>
/// 設置CPU
/// </summary>
ILGA1155 CPU
{
set;
}

/// <summary>
/// 設置SATA1插槽的設備
/// </summary>
ISATA SATA1
{
set;
}

/// <summary>
/// 設置SATA2插槽的設備
/// </summary>
ISATA SATA2
{
set;
}

/// <summary>
/// 設置內存條1#
/// </summary>
IDDR3 DIMM1
{
set;
}

/// <summary>
/// 設置內存條2#
/// </summary>
IDDR3 DIMM2
{
set;
}

/// <summary>
/// 設置PCI1插槽的設備
/// </summary>
IPCI PCI1
{
set;
}

/// <summary>
/// 設置PCI2插槽的設備
/// </summary>
IPCI PCI2
{
set;
}

/// <summary>
/// 設置顯卡
/// </summary>
IPCIExpress PCIExpress
{
set;
}
}

     OK,大家現在已經看到了,我們設計的這個H61主板上帶有一個CPU接口,兩個內存條接口,兩個硬盤接口,兩個PCI接口以及一個PCI-E接口,我們的主板已經為各種設備留出了接口,但並沒有依賴於具體某個設備,CPU、內存條等配件只要插在相應的插槽內即可使用。

     Well,設計完了接口,我們就該設計具體的實現了。仍然從CPU開始,之前我們已經設計好了ICpu和ILGA1155接口,考慮到代碼復用,我們先設計一個CpuBase類實現ICpu,這樣以后無論是哪種CPU都可以復用他們共有的屬性和方法,然后我們在建一個PentiumG620類表示Inter G620 CPU,PentiumG620類首先需要繼承CpuBase基類,又因為G620要根據LGA1155的接口標准去設計,所以又要實現ILGA1155,代碼如下:

View Code
    /// <summary>
/// CPU基類
/// </summary>
public class CpuBase : ICpu
{
#region --Fields--
private string mName;//CPU名稱
private float mSpeed;//主頻
private float mExClock;//外頻
private int mPinNumber;//針腳數
#endregion

#region --Properties--
/// <summary>
/// 獲取CPU名稱
/// </summary>
public string Name
{
get { return mName; }
}

/// <summary>
/// 獲取主頻
/// </summary>
public float Speed
{
get { return mSpeed; }
}

/// <summary>
/// 獲取外頻
/// </summary>
public float ExClock
{
get { return mExClock; }
}

/// <summary>
/// 獲取針腳數量
/// </summary>
public int PinNumber
{
get { return mPinNumber; }
}
#endregion

#region --Constructor--
/// <summary>
/// 默認構造方法
/// </summary>
public CpuBase()
{
}
#endregion

#region --Protected Methods--
/// <summary>
/// 設置CPU名稱
/// </summary>
/// <param name="name">cpu名稱</param>
protected void SetName(string name)
{
mName = name;
}

/// <summary>
/// 設置CPU主頻
/// </summary>
/// <param name="speed"></param>
protected void SetSpeed(float speed)
{
mSpeed = speed;
}

/// <summary>
/// 設置CPU外頻
/// </summary>
/// <param name="exClock"></param>
protected void SetExClock(float exClock)
{
mExClock = exClock;
}

/// <summary>
/// 設置CPU針腳數
/// </summary>
/// <param name="pinNumber"></param>
protected void SetPinNumber(int pinNumber)
{
mPinNumber = pinNumber;
}
#endregion

#region --Public Methods--
/// <summary>
/// 執行計算
/// </summary>
public virtual void Compute()
{

}

/// <summary>
/// 運行
/// </summary>
public void Run()
{

}
#endregion
}

public class PentiumG620 : CpuBase, ILGA1155
{
#region --Constructor--
public PentiumG620()
{
SetName("奔騰G620");
SetPinNumber(1155);
SetSpeed(2.6f);
SetExClock(0.1f);
}
#endregion
}

     如果子類需要重寫基類的方法,我們可以將基類中的方法設計成虛方法,這完全按需求來控制。

    CPU具體類設計完之后,我們再來設計內存的具體類。之前我們已經設計好了IDIMM和IDDR3接口,為了復用代碼我們我們先設計一個內存基類MemoryBase實現IDIMM接口,然后再建一個Kingston4gDDR3類表示具體的金士頓內存條,它需要繼承MemoryBase基類,並且需要實現IDDR3這個行業標准,代碼如下:

View Code
    /// <summary>
/// DDR3內存條基類
/// </summary>
public class MemoryBase : IDIMM
{
#region --Fields--
private string mName;
private string mSpeed;
private string mVolume;
#endregion

#region --Properties--
/// <summary>
/// 獲取內存名稱
/// </summary>
public string Name
{
get { return mName; }
}

/// <summary>
/// 獲取時鍾頻率
/// </summary>
public string Speed
{
get { return mSpeed; }
}

/// <summary>
/// 獲取容量
/// </summary>
public string Volume
{
get { return mVolume; }
}
#endregion

#region --Protected Methods--
/// <summary>
/// 設置內存名稱
/// </summary>
/// <param name="name"></param>
protected void SetName(string name)
{
mName = name;
}

/// <summary>
/// 設置內存時鍾頻率
/// </summary>
/// <param name="speed"></param>
protected void SetSpeed(string speed)
{
mSpeed = speed;
}

/// <summary>
/// 設置內存容量
/// </summary>
/// <param name="volume"></param>
protected void SetVolume(string volume)
{
mVolume = volume;
}
#endregion

#region --Public Methods--
/// <summary>
/// 運行
/// </summary>
public void Run()
{

}

/// <summary>
/// 停止
/// </summary>
public void Stop()
{

}
#endregion
}

public class Kingston4gDDR3 : MemoryBase, IDDR3
{
#region --Constructor--
/// <summary>
/// 默認構造方法
/// </summary>
public Kingston4gDDR3()
{
SetName("金士頓 DDR3 4G");
SetSpeed("1333MHz");
SetVolume("4G");
}
#endregion
}

    

      OK,下面輪到硬盤了,之前已經設計好了ISATA接口,與內存和CPU一樣,硬盤也需要一個基類,先新建一個HardDiscBase實現ISATA接口,然后我們在建一個WD500類表示一個西數的具體硬盤,它需要繼承HardDiscBase類,代碼如下:

View Code
    /// <summary>
/// 硬盤基類
/// </summary>
public class HardDiscBase : ISATA
{
#region --Fields--
private string mName;
private string mSpeed;
private string mSize;
#endregion

#region --Properties--
/// <summary>
/// 獲取硬盤容量
/// </summary>
public string Size
{
get { return mSize; }
}

/// <summary>
/// 獲取硬盤名稱
/// </summary>
public string Name
{
get { return mName; }
}

/// <summary>
/// 獲取傳輸速度
/// </summary>
public string Speed
{
get { return mSpeed; }
}
#endregion

#region --Protected Methods--
/// <summary>
/// 設置硬盤的名稱
/// </summary>
/// <param name="name"></param>
protected void SetName(string name)
{
mName = name;
}

/// <summary>
/// 設置硬盤的傳輸速度
/// </summary>
/// <param name="speed"></param>
protected void SetSpeed(string speed)
{
mSpeed = speed;
}

/// <summary>
/// 設置硬盤容量
/// </summary>
/// <param name="size"></param>
protected void SetSize(string size)
{
mSize = size;
}
#endregion

#region --Public Methods--
/// <summary>
/// 運行
/// </summary>
public void Run()
{

}

/// <summary>
/// 停止
/// </summary>
public void Stop()
{

}

/// <summary>
/// 發送數據
/// </summary>
public void Send()
{

}

/// <summary>
/// 接收數據
/// </summary>
public void Receive()
{

}
#endregion
}

public class WD500 : HardDiscBase
{
#region --Constructor--
/// <summary>
/// 默認構造方法
/// </summary>
public WD500()
{
SetName("西部數據 藍盤");
SetSpeed("6Gbps");
SetSize("500G");
}
#endregion
}

    

     設計完硬盤,再把顯卡也設計一下。顯卡的設計當然是要符合PCI-E的接口標准,之前我們已經設計好了IPCI和IPCIExpress接口,首先新建一個PCIDeviceBase類實現IPCI,以它作為PCI設備的基類,然后,再建一個GalaxyGTS450類表示一個具體的影馳顯卡,它需要繼承PCIDeviceBase基類並且要實現IPCIExpress接口標准。代碼如下:

View Code
    /// <summary>
/// PCI設備基類
/// </summary>
public class PCIDeviceBase : IPCI
{
#region --Fields--
private string mName;
#endregion

#region --Properties--
/// <summary>
/// 獲取PCI設備名稱
/// </summary>
public string Name
{
get { return mName; }
}
#endregion

#region --Constructor--
/// <summary>
/// 默認構造方法
/// </summary>
public PCIDeviceBase()
{

}
#endregion

#region --Protected Methods--
/// <summary>
/// 設置PCI設備名稱
/// </summary>
/// <param name="name"></param>
protected void SetName(string name)
{
mName = name;
}
#endregion

#region --Public Methods--
/// <summary>
/// 運行
/// </summary>
public void Run()
{

}

/// <summary>
/// 停止
/// </summary>
public void Stop()
{

}
#endregion
}


public class GalaxyGTS450 : PCIDeviceBase, IPCIExpress
{
#region --Fields--
private string mGPUName;
private string mMemoryType;
private string mMemorySize;
private string mMemoryClock;
private string mCoreClock;
private int mBitWidth;
#endregion

#region --Properties--
/// <summary>
/// 獲取顯示芯片名稱
/// </summary>
public string GPUName
{
get { return mGPUName; }
}

/// <summary>
/// 獲取顯存類型
/// </summary>
public string MemoryType
{
get { return mMemoryType; }
}

/// <summary>
/// 獲取顯存容量
/// </summary>
public string MemorySize
{
get { return mMemorySize; }
}

/// <summary>
/// 獲取顯存位寬
/// </summary>
public int BitWidth
{
get { return mBitWidth; }
}

/// <summary>
/// 獲取顯存頻率
/// </summary>
public string MemoryClock
{
get { return mMemoryClock; }
}

/// <summary>
/// 獲取核心頻率
/// </summary>
public string CoreClock
{
get { return mCoreClock; }
}
#endregion

#region --Constructor--
/// <summary>
/// 默認構造方法
/// </summary>
public GalaxyGTS450()
{
SetName("影馳GTS450重炮手");
mGPUName = "NVIDIA Geforce GTS450";
mMemoryType = "GDDR5";
mMemorySize = "512MB";
mMemoryClock = "3600MHz";
mCoreClock = "783MHz";
mBitWidth = 128;
}
#endregion
}

    

    現在關鍵配件都已設計完成,就差主板了。主板的具體類設計也很簡單,首先新建一個MainboardBase類實現IMainboard,以它作為主板的基類,然后再建一個MsiH61Mainboard類用來表示一個具體的H61主板,它需要繼承MainboardBase基類並且要實現IH61芯片組的接口標准,代碼如下:

View Code
    /// <summary>
/// 主板基類
/// </summary>
public class MainboardBase : IMainboard
{
#region --Fields--
private string mName;
#endregion

#region --Properties--
/// <summary>
/// 獲取主板名稱
/// </summary>
public string Name
{
get { return mName; }
}
#endregion

#region --Protected Methods--
/// <summary>
/// 設置主板名稱
/// </summary>
/// <param name="name"></param>
protected void SetName(string name)
{
mName = name;
}
#endregion

#region --Public Methods--
/// <summary>
/// 運行
/// </summary>
public virtual string Run()
{
return "";
}

/// <summary>
/// 停止
/// </summary>
public void Stop()
{

}
#endregion
}


public class MsiH61Mainboard : MainboardBase, IH61
{
#region --Fields--
private ILGA1155 mCpu;
private ISATA mSata1;
private ISATA mSata2;
private IDDR3 mDimm1;
private IDDR3 mDimm2;
private IPCI mPci1;
private IPCI mPci2;
private IPCIExpress mPciExpress;
#endregion

#region --Properties--
/// <summary>
/// 設置CPU
/// </summary>
public ILGA1155 CPU
{
set { mCpu = value; }
}

/// <summary>
/// 設置硬盤
/// </summary>
public ISATA SATA1
{
set { mSata1 = value; }
}

/// <summary>
/// 設置SATA2插槽的設備
/// </summary>
public ISATA SATA2
{
set { mSata2 = value; }
}

/// <summary>
/// 設置內存條1#
/// </summary>
public IDDR3 DIMM1
{
set { mDimm1 = value; }
}

/// <summary>
/// 設置內存條2#
/// </summary>
public IDDR3 DIMM2
{
set { mDimm2 = value; }
}

/// <summary>
/// 設置PCI1插槽的設備
/// </summary>
public IPCI PCI1
{
set { mPci1 = value; }
}

/// <summary>
/// 設置PCI2插槽的設備
/// </summary>
public IPCI PCI2
{
set { mPci2 = value; }
}

/// <summary>
/// 設置顯卡
/// </summary>
public IPCIExpress PCIExpress
{
set { mPciExpress = value; }
}
#endregion

#region --Constructor--
/// <summary>
/// 默認構造方法
/// </summary>
public MsiH61Mainboard()
{
SetName("微星H61主板");
}
#endregion

#region --Public Methods--
/// <summary>
/// 運行
/// </summary>
public override string Run()
{
string rebackMsg = "硬件檢測:\r\n";
string mainboardInfo = "主板:" + Name;
string harddiscInfo = "缺少硬盤";
string cpuInfo = "缺少CPU";
string memoryInfo = "缺少內存條";
string videoCardInfo = "缺少顯卡";
if (mSata1 != null)
{
harddiscInfo = mSata1.Name + "/" + mSata1.Size + "/" + mSata1.Speed;
}
if (mSata2 != null)
{
harddiscInfo = mSata2.Name + "/" + mSata2.Size + "/" + mSata2.Speed;
}
if (mCpu != null)
{
cpuInfo = mCpu.Name + "/主頻:" + mCpu.Speed + "GHz";
}
if (mDimm1 != null)
{
memoryInfo = mDimm1.Name + "/" + mDimm1.Volume;
}
if (mPciExpress != null)
{
videoCardInfo = mPciExpress.Name + "/" + mPciExpress.MemorySize;
}
rebackMsg += mainboardInfo + "\r\nCPU:" + cpuInfo + "\r\n內存:" + memoryInfo
+ "\r\n硬盤:" + harddiscInfo + "\r\n顯卡:" + videoCardInfo;
return rebackMsg;
}
#endregion
}

    在MsiH61Mainboard類的Run()方法里,我寫了一段硬件檢測的代碼,用於顯示我們插在主板上的硬件信息。

    OK,到這里我們的設計就已經全部完成了,終於到派上用場的時候了,讓我們親手組裝一台電腦,代碼如下:

View Code
   class Program
{
static void Main(string[] args)
{
//實例化各個配件
ISATA harddisc = new WD500();
ILGA1155 cpu = new PentiumG620();
IDDR3 memory = new Kingston4gDDR3();
IPCIExpress videoCard = new GalaxyGTS450();
IH61 mainboard = new MsiH61Mainboard();
mainboard.SATA1 = harddisc;//將硬盤插在主板上
mainboard.CPU = cpu;//將CPU插在主板上
mainboard.DIMM1 = memory;//將內存條插在主板上
mainboard.PCIExpress = videoCard;//將顯卡插在主板上
string rebackMsg = mainboard.Run();//加電運行
Console.WriteLine(rebackMsg);
Console.ReadLine();
}
}

運行結果如下圖所示:

   

     好了,現在我感覺奔騰G620在運行大型游戲時有些卡,我想要將CPU更換成Corei3,這該怎么辦。嘿嘿,沒關系,我們之前的設計早就為這種變化留出了空間。只需要新建一個Corei3類,和PentiumG620的設計一樣,Corei3需要繼承CpuBase並實現ILGA1155,代碼如下:、

View Code
    public class Corei3 : CpuBase, ILGA1155
{
#region --Constructor--
/// <summary>
/// 默認構造方法
/// </summary>
public Corei3()
{
SetName("Corei3 2100");
SetPinNumber(1155);
SetSpeed(3.1f);
SetExClock(0.1f);
}
#endregion

#region --Public Methods--
/// <summary>
/// 執行計算
/// </summary>
public override void Compute()
{

}
#endregion
}

     在Main方法中,需要做的只是實例化Corei3並把它插在主板的CPU插槽上,代碼如下:

View Code
ILGA1155 cpu = new Corei3();
mainboard.CPU = cpu;//將CPU插在主板上

     更換CPU后的運行結果如圖所示:

 

     以這樣的方式應對變化是不是很好啊,呵呵。這里也體現了擴展-封閉原則,即對擴展開放,對修改封閉,我們要更換CPU只要再買一個Corei3,把它插在主板上就可以了,其他任何配件都沒受到影響,難道我們還要把G620拆開去重新修改它的內部架構嗎,這在現實生活中顯然也是不允許的。

PS:本文是我在清理電腦時的一點感觸,並不是真正模擬計算機組成的例子,只是借此來描述面向對象的一些思想,希望能對剛接觸面向對象的童鞋們一點啟發。本人才疏學淺,文筆不精,文中有不合理語句或理解錯誤的地方還請大家多指正。

     大家可以到這里下載本文例子 http://files.cnblogs.com/yanchenglong/PortDemo.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM