<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>思维 &#187; 抽象</title>
	<atom:link href="http://blog.acmind.com/archives/tag/%e6%8a%bd%e8%b1%a1/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.acmind.com</link>
	<description>Acme of Mind</description>
	<lastBuildDate>Mon, 19 Apr 2010 02:23:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>C#类和接口、虚方法和抽象方法及值类型和引用类型的区别</title>
		<link>http://blog.acmind.com/archives/339</link>
		<comments>http://blog.acmind.com/archives/339#comments</comments>
		<pubDate>Wed, 27 May 2009 04:09:33 +0000</pubDate>
		<dc:creator>笑谈</dc:creator>
				<category><![CDATA[设计技巧]]></category>
		<category><![CDATA[引用]]></category>
		<category><![CDATA[值]]></category>
		<category><![CDATA[类]]></category>
		<category><![CDATA[虚方法]]></category>
		<category><![CDATA[抽象]]></category>
		<category><![CDATA[接口]]></category>

		<guid isPermaLink="false">http://blog.acmind.com/?p=339</guid>
		<description><![CDATA[1.C#类和接口的区别   解答：    接口是负责功能的定义，项目中通过接口来规范类，操作类以及抽象类的概念！    而类是负责功能的具体实现！    在类中也有抽象类的定义，抽象类与接口的区别在于：    抽象类是一个不完全的类，类里面有抽象的方法，属性，也可以有具体的方法和属性，需要进一步的专业化。    但接口是一个行为的规范，里面的所有东西都是抽象的！    一个类只可以继承一个基类也就是父类，但可以实现多个接口    PS： 接口除了规范一个行为之外，在具体项目中的实际作用也是十分重要的，在面向对象的设计原则以及设计模式的使用中，无不体现作为一个接口的使用好处，最直接 的就是设计原则中OCP（开放封闭原则），我们使用接口，而不需要关心他的具体实现，具体实现的细节变化也无关客户端（使用接口的类）的使用，对与扩展是 开放的，我们可以另写一个接口的实现来扩展当前程序，而不影响上层的使用，但对修改是封闭的，即我们不能够再去修改接口的定义，当然这个“不能够”是指在 规范原则上不应该这么做！
2.抽象类和接口的区别    解答：    抽象类（abstract class）可以包含功能定义和实现，接口（interface）只能包含功能定义    抽象类是从一系列相关对象中抽象出来的概念， 因此反映的是事物的内部共性；接口是为了满足外部调用而定义的一个功能约定， 因此反映的是事物的外部特性    分析对象，提炼内部共性形成抽象类，用以表示对象本质，即“是什么” [...]]]></description>
			<content:encoded><![CDATA[<p>1.C#类和接口的区别   <br />解答：    <br />接口是负责功能的定义，项目中通过接口来规范类，操作类以及抽象类的概念！    <br />而类是负责功能的具体实现！    <br />在类中也有抽象类的定义，抽象类与接口的区别在于：    <br />抽象类是一个不完全的类，类里面有抽象的方法，属性，也可以有具体的方法和属性，需要进一步的专业化。    <br />但接口是一个行为的规范，里面的所有东西都是抽象的！    <br />一个类只可以继承一个基类也就是父类，但可以实现多个接口    <br />PS： 接口除了规范一个行为之外，在具体项目中的实际作用也是十分重要的，在面向对象的设计原则以及设计模式的使用中，无不体现作为一个接口的使用好处，最直接 的就是设计原则中OCP（开放封闭原则），我们使用接口，而不需要关心他的具体实现，具体实现的细节变化也无关客户端（使用接口的类）的使用，对与扩展是 开放的，我们可以另写一个接口的实现来扩展当前程序，而不影响上层的使用，但对修改是封闭的，即我们不能够再去修改接口的定义，当然这个“不能够”是指在 规范原则上不应该这么做！</p>
<p>2.抽象类和接口的区别    <br />解答：    <br />抽象类（abstract class）可以包含功能定义和实现，接口（interface）只能包含功能定义    <br />抽象类是从一系列相关对象中抽象出来的概念， 因此反映的是事物的内部共性；接口是为了满足外部调用而定义的一个功能约定， 因此反映的是事物的外部特性    <br />分析对象，提炼内部共性形成抽象类，用以表示对象本质，即“是什么”     <br />为外部提供调用或功能需要扩充时优先使用接口</p>
<p>3. C#语言中，值类型和引用类型有何不同     <br />解答：    <br />值类型和引用类型的区别在于，值类型的变量直接存放实际的数据，而引用类型的变量存放的则是数据的地址，即对象的引用。    <br />值类型变量直接把变量的值保存在堆栈中，引用类型的变量把实际数据的地址保存在堆栈中，而实际数据则保存在堆中。注意，堆和堆栈是两个不同的概念，在内存中的存储位置也不相同，堆一般用于存储可变长度的数据，如字符串类型;而堆栈则用于存储固定长度的数据，如整型类型的数据int(每个int变量占用四 个字节)。由数据存储的位置可以得知，当把一个值变量赋给另一个值变量时，会在堆栈中保存两个完全相同的值;而把一个引用变量赋给另一个引用变量，则会在 堆栈中保存对同一个堆位置的两个引用，即在堆栈中保存的是同一个堆的地址。在进行数据操作时，对于值类型，由于每个变量都有自己的值，因此对一个变量的操 作不会影响到其它变量;对于引用类型的变量，对一个变量的数据进行操作就是对这个变量在堆中的数据进行操作，如果两个引用类型的变量引用同一个对象，实际 含义就是它们在堆栈中保存的堆的地址相同，因此对一个变量的操作就会影响到引用同一个对象的另一个变量。</p>
<p>4.结构和类的区别    <br />解答：    <br />1) 结构是一个值类型，保存在栈上，而类是一个引用类型，保存在受管制的堆上。    <br />2) 对结构中的数据进行操作比对类或对象中的数据进行操作速度要快。    <br />3) 一般用结构存储多种类型的数据，当创建一个很多类或对象共用的小型对象时，使用结构效率更高。</p>
<p>4.抽象方法和虚方法的区别    <br />解答：    <br />抽象方法    <br />使用abstract关键字 public abstract bool Withdraw(…);     <br />抽象方法是必须被派生类覆写的方法。    <br />抽象方法是可以看成是没有实现体的虚方法    <br />如果类中包含抽象方法，那么类就必须定义为抽象类，不论是否还包含其它一般方法    <br />虚方法    <br />使用virtual关键字 public virtual bool Withdraw(…);     <br />调用虚方法，运行时将确定调用对象是什么类的实例，并调用适当的覆写的方法。    <br />虚方法可以有实现体    <br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;     <br />虚拟方法和抽象方法有什么区别？    <br />抽象方法只有声明没有实现，需要在子类中实现；虚拟方法有声明和实现，并且可以在子类中覆盖，也可以不覆盖使用父类的默认实现    <br />虚拟方法有实现代码    <br />抽象方法则没有，    <br />并且抽象类不能被实例化，只能实例化实现了全部抽象方法的派生类    <br />抽象方法是虚拟方法的一种    <br />抽象方法没有实现，它的存在只是为派生类统一接口；派生类应该实现这个方法    <br />如果编写一个基类，它永远不会被实现，那么就应该将这个类中的一个或多个方法定义为    <br />抽象方法。    <br />抽象方法只有声明没有实现，需要在子类中实现；虚拟方法有声明和实现，并且可以在子类中覆盖，也可以不覆盖使用父类的默认实现    <br />补充一点    <br />只允许在抽象类中使用抽象方法声明    <br />学习    <br />其实大家首先要搞清楚，虚方法与多态性关系密切，虚方法允许派生类完全或部分重写该类的方法，需写方法体。抽象类中可以包含抽象方法与一般的方法，抽象类不 可以new,抽象方法只是一个定义，没有方法体，也就是没有{}，也不要在里面写内容。它们两个相像的一点是都用override重写</p>
<p>&#160;</p>
<p>摘自：<a title="http://www.zxbc.cn/html/20090419/70325.html" href="http://www.zxbc.cn/html/20090419/70325.html">http://www.zxbc.cn/html/20090419/70325.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.acmind.com/archives/339/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>抽象工厂模式</title>
		<link>http://blog.acmind.com/archives/129</link>
		<comments>http://blog.acmind.com/archives/129#comments</comments>
		<pubDate>Sat, 17 Jan 2009 02:10:26 +0000</pubDate>
		<dc:creator>笑谈</dc:creator>
				<category><![CDATA[架构分析]]></category>
		<category><![CDATA[工厂]]></category>
		<category><![CDATA[设计技巧]]></category>
		<category><![CDATA[设计模式]]></category>
		<category><![CDATA[抽象]]></category>
		<category><![CDATA[模式]]></category>

		<guid isPermaLink="false">http://blog.acmind.com/?p=129</guid>
		<description><![CDATA[ 
User.cs
class User
{
    private int _id;
    public int ID
    {
        get { return _id; }
        set { _id = value; }
    }

    private string _name;
  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.acmind.com/wp-content/uploads/2009/01/image11.png" class="highslide-image" onclick="return hs.expand(this);"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="500" alt="image" src="http://blog.acmind.com/wp-content/uploads/2009/01/image-thumb11.png" width="652" border="0" /></a> </p>
<p>User.cs</p>
<pre class="mycode"><span style="color: #0000ff">class</span> User
{
    <span style="color: #0000ff">private</span> <span style="color: #0000ff">int</span> _id;
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> ID
    {
        <span style="color: #0000ff">get</span> { <span style="color: #0000ff">return</span> _id; }
        <span style="color: #0000ff">set</span> { _id = <span style="color: #0000ff">value</span>; }
    }

    <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> _name;
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> NAME
    {
        <span style="color: #0000ff">get</span> { <span style="color: #0000ff">return</span> _name; }
        <span style="color: #0000ff">set</span> { _name = <span style="color: #0000ff">value</span>; }
    }
}</pre>
<p>IUser.cs</p>
<pre class="mycode"><span style="color: #0000ff">interface</span> IUser
{
    <span style="color: #0000ff">void</span> Insert(User user);

    User GetUser(<span style="color: #0000ff">int</span> id);
}</pre>
<p>SqlserverUser.cs</p>
<pre class="mycode"><span style="color: #0000ff">class</span> SqlserverUser : IUser
{
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Insert(User user)
    {
        Console.WriteLine(&quot;<span style="color: #8b0000">在SQL Server中给User表增加一条记录。</span>&quot;);
    }

    <span style="color: #0000ff">public</span> User GetUser(<span style="color: #0000ff">int</span> id)
    {
        Console.WriteLine(&quot;<span style="color: #8b0000">在SQL Server中根据ID得到User表一条记录。</span>&quot;);
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;
    }
}</pre>
<p>AccessUser.cs</p>
<pre class="mycode"><span style="color: #0000ff">class</span> AccessUser : IUser
{
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Insert(User user)
    {
        Console.WriteLine(&quot;<span style="color: #8b0000">在Access中给User表增加一条记录。</span>&quot;);
    }

    <span style="color: #0000ff">public</span> User GetUser(<span style="color: #0000ff">int</span> id)
    {
        Console.WriteLine(&quot;<span style="color: #8b0000">在Access中根据ID得到User表一条记录。</span>&quot;);
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;
    }
}</pre>
<p>Department.cs</p>
<pre class="mycode"><span style="color: #0000ff">class</span> Department
{
    <span style="color: #0000ff">private</span> <span style="color: #0000ff">int</span> _id;
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> ID
    {
        <span style="color: #0000ff">get</span> { <span style="color: #0000ff">return</span> _id; }
        <span style="color: #0000ff">set</span> { _id = <span style="color: #0000ff">value</span>; }
    }

    <span style="color: #0000ff">private</span> <span style="color: #0000ff">string</span> _deptName;
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> DeptName
    {
        <span style="color: #0000ff">get</span> { <span style="color: #0000ff">return</span> _deptName; }
        <span style="color: #0000ff">set</span> { _deptName = <span style="color: #0000ff">value</span>; }
    }
}</pre>
<p>IDepartment.cs</p>
<pre class="mycode"><span style="color: #0000ff">interface</span> IDepartment
{
    <span style="color: #0000ff">void</span> Insert(Department department);

    Department GetDepartment(<span style="color: #0000ff">int</span> id);
}</pre>
<p>SqlserverDepartment.cs</p>
<pre class="mycode"><span style="color: #0000ff">class</span> SqlserverDepartment : IDepartment
{
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Insert(Department department)
    {
        Console.WriteLine(&quot;<span style="color: #8b0000">在SQL Server中给Department表增加一条记录。</span>&quot;);
    }

    <span style="color: #0000ff">public</span> Department GetDepartment(<span style="color: #0000ff">int</span> id)
    {
        Console.WriteLine(&quot;<span style="color: #8b0000">在SQL Server中根据ID得到Department表一条记录。</span>&quot;);
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;
    }
}</pre>
<p>AccessDepartment.cs</p>
<pre class="mycode"><span style="color: #0000ff">class</span> AccessDepartment : IDepartment
{
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Insert(Department department)
    {
        Console.WriteLine(&quot;<span style="color: #8b0000">在Access中给Department表增加一条记录。</span>&quot;);
    }

    <span style="color: #0000ff">public</span> Department GetDepartment(<span style="color: #0000ff">int</span> id)
    {
        Console.WriteLine(&quot;<span style="color: #8b0000">在Access中根据ID得到Department表一条记录。</span>&quot;);
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;
    }
}</pre>
<p>IFactory.cs</p>
<pre class="mycode"><span style="color: #0000ff">interface</span> IFactory
{
    IUser CreateUser();

    IDepartment CreateDepartment();
}</pre>
<p>SqlserverFactory.cs</p>
<pre class="mycode"><span style="color: #0000ff">class</span> SqlserverFactory : IFactory
{
    <span style="color: #0000ff">public</span> IUser CreateUser()
    {
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> SqlserverUser();
    }

    <span style="color: #0000ff">public</span> IDepartment CreateDepartment()
    {
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> SqlserverDepartment();
    }
}</pre>
<p>AccessFactory.cs</p>
<pre class="mycode"><span style="color: #0000ff">class</span> AccessFactory : IFactory
{
    <span style="color: #0000ff">public</span> IUser CreateUser()
    {
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> AccessUser();
    }

    <span style="color: #0000ff">public</span> IDepartment CreateDepartment()
    {
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> AccessDepartment();
    }
}</pre>
<p>Client.cs</p>
<pre class="mycode"><span style="color: #0000ff">class</span> Client
{
    <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> Main(<span style="color: #0000ff">string</span>[] args)
    {
        User user = <span style="color: #0000ff">new</span> User();
        Department department = <span style="color: #0000ff">new</span> Department();

        IFactory factory = <span style="color: #0000ff">new</span> SqlserverFactory();
        <span style="color: #008000">//IFactory factory = new AccessFactory();</span>

        IUser iu = factory.CreateUser();
        iu.Insert(user);
        iu.GetUser(1);

        IDepartment id = factory.CreateDepartment();
        id.Insert(department);
        id.GetDepartment(1);

        Console.Read();
    }
}</pre>
<p><strong>小结：</strong></p>
<ul>
<li><strong>本例分析：只有一个User类和User操作类时，是只需要工厂模式的，但现在加入新表，而且SQL Server与Access又是两大不同的分类，所以解决这种涉及多个产品系列的问题，用到了抽象工厂模式。</strong> </li>
<li><strong>优点：最大的好处是易于交换产品系列，由于具体工厂类，如IFactory factory=new AccessFactory()，在一个应用中只需要在初始化时出现一次，这就使得改变一个应用的具体工厂变得非常容易，它只需要改变具体工厂即可使用不同的产品配置；第二大好处是，它让具体的创建实例过程与客户端分离，客户端是通过它们的抽象接口操纵实例，产品的具体类名也被具体工厂的实现分离，不会出现在客户代码中。</strong> </li>
<li><strong>缺点：比如我们要增加项目表Project，至少要增加三个类，IProject、SqlserverProject、AccessProject，还需要更改IFactory、SqlserverFactory和AccessFactory才可以完全实现；另外，客户端程序类不只一个时，很多地方都在用IUser或IDepartment，每一个类在开始都会声明IFactory factory=new SqlserverFactory()，如果我有100个调用数据库的类，就要更改100次IFactory factory=new SqlserverFactory()。［此种情况时可以考虑用简单工厂模式＋抽象工厂模式进行，随后也可以再过渡到反射＋抽象工厂模式（反射＋配置文件）］。</strong> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.acmind.com/archives/129/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>简单工厂模式VS.工厂方法模式</title>
		<link>http://blog.acmind.com/archives/126</link>
		<comments>http://blog.acmind.com/archives/126#comments</comments>
		<pubDate>Sat, 17 Jan 2009 01:58:09 +0000</pubDate>
		<dc:creator>笑谈</dc:creator>
				<category><![CDATA[架构分析]]></category>
		<category><![CDATA[工厂]]></category>
		<category><![CDATA[简单]]></category>
		<category><![CDATA[设计技巧]]></category>
		<category><![CDATA[设计模式]]></category>
		<category><![CDATA[抽象]]></category>
		<category><![CDATA[模式]]></category>

		<guid isPermaLink="false">http://blog.acmind.com/?p=126</guid>
		<description><![CDATA[先将上面2个图拿出来做比较：
简单工厂：

工厂方法：

1、简单工厂模式下，工厂类与具体父类及具体子类都有关联；而工厂模式下，工厂类只与具体父类有关联，由工厂子类负责与具体子类进行关联。
2、如果在简单工厂模式下加入新功能扩展，就要对工厂类做修改，加入新功能；而在工厂模式下，只是单纯地加入工厂子类和具体子类，而不需要对工厂类做修改，做到了“开放扩展，封闭修改”。
3、其实尽管对工厂类不需要做修改了，但是也要对客户端做修改，因为添加了对新功能的调用。也就是说工厂模式做到了对工厂类的开闭原则，却解决不了对客户端的修改。
4、一些情况下，可以考虑用工厂模式＋反射来解决客户端修改问题。
]]></description>
			<content:encoded><![CDATA[<p>先将上面2个图拿出来做比较：</p>
<p>简单工厂：</p>
<p><a href="http://blog.acmind.com/wp-content/uploads/2009/01/clip-image0011.jpg" class="highslide-image" onclick="return hs.expand(this);"><img title="clip_image001" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="343" alt="clip_image001" src="http://blog.acmind.com/wp-content/uploads/2009/01/clip-image001-thumb1.jpg" width="531" border="0" /></a></p>
<p>工厂方法：</p>
<p><a href="http://blog.acmind.com/wp-content/uploads/2009/01/clip-image0021.jpg" class="highslide-image" onclick="return hs.expand(this);"><img title="clip_image002" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="389" alt="clip_image002" src="http://blog.acmind.com/wp-content/uploads/2009/01/clip-image002-thumb2.jpg" width="673" border="0" /></a></p>
<p>1、简单工厂模式下，工厂类与具体父类及具体子类都有关联；而工厂模式下，工厂类只与具体父类有关联，由工厂子类负责与具体子类进行关联。</p>
<p>2、如果在简单工厂模式下加入新功能扩展，就要对工厂类做修改，加入新功能；而在工厂模式下，只是单纯地加入工厂子类和具体子类，而不需要对工厂类做修改，做到了“开放扩展，封闭修改”。</p>
<p>3、其实尽管对工厂类不需要做修改了，但是也要对客户端做修改，因为添加了对新功能的调用。也就是说工厂模式做到了对工厂类的开闭原则，却解决不了对客户端的修改。</p>
<p>4、一些情况下，可以考虑用工厂模式＋反射来解决客户端修改问题。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.acmind.com/archives/126/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

