由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

转载于:https://www.cnblogs.com/yanchenglong/archive/2012/01/28/2330469.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值