昨天,我把家里的主机清理了一下,那个脏啊,上次清理还是一年前,机箱里的灰尘可都够做一桌菜了,呵呵。我把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

由DIY想到的面向对象思想相关推荐

  1. 从DIY想到的面向对象的思想

    昨天,我把家里的主机清理了一下,那个脏啊,上次清理还是一年前,机箱里的灰尘可都够做一桌菜了,呵呵.我把CPU.内存条.显卡等都拔了下来挨个清理,可是费了好大功夫.我是一个DIY爱好者,在清理过程中不时 ...

  2. 树结构之树和二叉树的概念以及如何用面向对象思想进行结构定义01

    树和二叉树的概念及结构定义 前言 一.树的基本概念及代码层面如何定义 1.树的概念 2.代码层面树如何定义 二.二叉树的基本概念及代码层面如何定义 1.二叉树的概念 2.代码层面二叉树如何定义 3.二 ...

  3. 浅谈面向对象思想下的 C 语言

    如何使用OO思维方式 面向对象(object Oriented,简称:OO)在于用"找对象"的方式去规划和描述问题. 一.怎样"找对象" (思维过程) &quo ...

  4. 面向对象思想(详解)

    一.面向过程编程与面向对象编程 1.什么是面向过程编程? 面向过程其实是最为实际的一种思考方式,就是算面向对象的方法也是含有面向过程的思想.可以说面向过程是一种基础的方法,它考虑的是实际的实现一般的面 ...

  5. Java中对于面向对象思想的理解

    1. ① 与C语言面向过程不同的是,C语言中函数是主体,如果需要修改数据需要函数来进行修改,所以来说函数在C语言中是很重要的,基本上对于数据的操作都是这样的,但是有的时候不太方便,而Java语言面向对 ...

  6. 第0篇 面向对象思想

    一 面向对象思想的起源 面向对象(Object-Oriented)思想最初起源于20世纪60年代末的simula67语言.面向对象方法的基本要点首次在simula语言中得到了表达和实现.80年代,位于 ...

  7. 前端小白用面向对象思想实现元素拖拽

    上篇文章分享了如何用面向对象思想编写选项卡,在文章最后留了一个拖拽的例子,希望大家可以试着写一下,现在我就谈谈我在这过程中遇到的一些问题和解决方法.(本文主要是想和js初学者分享经验,代码中的更改th ...

  8. java有无参数求长方形的周长面积_用java面向对象思想编程求长方形的周长和面积...

    //面向的重要体现就是接口的使用 //甲 interface zfx { double mianji(); double zhchang(); } //乙 class zfxing implement ...

  9. 四大发明之活字印刷——面向对象思想的胜利

    四大发明之活字印刷--面向对象思想的胜利 话说三国时期,曹操带领百万大军攻打东吴,大军在长江赤壁驻扎,军船连成一片,眼看就要灭掉东吴,统一天下,曹操大悦,于是大宴众文武,在酒席间,曹操诗性大发,不觉吟 ...

最新文章

  1. c++人脸特征保存到本地_尚邦小规模人脸识别布控系统
  2. 【poj1088 记忆话搜索】
  3. Python基础06 循环
  4. 杜克大学计算机硕士要几年,2017杜克大学春季不招计算机专业的硕士?
  5. win10 .net framework 3.5 0x800F0954
  6. WordPress中自带的处理AJAX请求的HOOK
  7. SQL SERVER 查找某个字符在字符串中出现的次数
  8. 小D课堂 - 新版本微服务springcloud+Docker教程_3-04 SpringCloud微服务核心组件Eureka介绍和闭源后影响...
  9. 从零开始Android游戏编程(第二版) 第十章 游戏循环的设计
  10. 使用WePE对无法启动的系统文件进行操作
  11. 如何带好一支团队,持续更新
  12. opengl绘制卡通人物哆啦A梦
  13. uniapp登录页面加入图片验证码
  14. 用计算机升级ipad系统软件,iPad如何升级系统?三种ipad升级系统的方法汇总
  15. BIM在工程中的20种典型应用
  16. 计算机软件产业分析,中国工业软件产业链上中下游布局分析及企业一览(附图表)...
  17. Winform实现光盘刻录功能
  18. matlab2016 新建m文件,matlab2016a关联m文件
  19. CF K. City
  20. C# 使用VS 性能探查器(快捷键:Alt+F2)

热门文章

  1. 【SAP Abap】SAP第四代增强开发DEMO
  2. HashMap-源码解读
  3. 【转载】尼康D90购机注意事项
  4. HyperWorks针对焊点信息丢失的处理办法
  5. 关于大数据技术原理与应用的学习(4)
  6. Windows cmd命令 个人常用0529
  7. android手机如何到导出电话号码,手机通讯录怎么导入到新手机?三种方法,快速迁移!...
  8. 指针的步长及意义(C语言基础)
  9. c++ map的遍历
  10. Appium基础篇9-元素定位之by_xpath