舞步者

带她一起去周游世界
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

设计模式之六Prototype(原型)模式

Posted on 2008-05-26 22:08  Kevin_Zhang  阅读(103)  评论(0)    收藏  举报
我们知道Abstract  Factory模式,Factory  Method模式以及Builder模式都需要额外一个工厂类来负责实例化易变对象,那么我们可以想象这么一种情形,如果这个易变对象将来会有好多种情形,那么我们的子类要不断的增加新类,在这种方式下,原型模式就起到了一个简化的作用
我们这里借用用Terrylee博文中所举的例子来说明:
 我们要做一个调色板程序,面板的每一个小的方块区域都代表一种颜色,那么按照我们之前的想法,我们最有可能采用工厂模式来进行处理:
首先抽象出颜色的基类aColor,抽象方法ShouColor
 public abstract class aColor
    
{
       
public abstract void ShowColor();
    }
然后创建具体的颜色类,作为aColor的实现类:
类RedColor:
 public class RedColor:aColor
    
{
        
public override void ShowColor()
        
{
            Console.WriteLine(
"This is Red");
        }

    }
类YellowColor:
 public class YellowColor:aColor
    
{
        
public override void ShowColor()
        
{
            Console.WriteLine(
"This is Yellow");
        }

    }
显然到这一步并不能完全实现客户程序与具体类的解耦,因为客户代码里面肯定会有这样的代码
aColor color=new RedColor();
color.ShowColor();
这里需要注意的是,我们的客户代码中出现这样的语句的地方可能不止一处,甚至有很多出,那么一旦需求改变,我们的new部分都要作改变
那么为了处理这个问题,我们知道这个地方是个变化点,那么按照原则我们应该封装这个变化点:我们给每个颜色都对应的增加一个工厂类,同时也抽象出一个基类,也即每个产品类都对应一个产品工厂类,我们可以将它们对应的同一个文件里,比如RedColor类可以和RedColorFactory类放在一个文件里。
抽象类aColorFactory:
 public abstract class aColorFactory
   
{
       
public abstract aColor Create();
   }
具体颜色实现类:
public class RedColorFactory : aColorFactory
    
{
        
public override aColor Create()
        
{
            
return (aColor)new RedColor();
        }

    }

 public class YellowColorFactory : aColorFactory
    
{
        
public override aColor Create()
        
{
            
return (aColor)new YellowColor();
        }

    }
那么这个时候,我们的客户代码调用可能会是另一种情形:
aColorFactory factory = (aColorFactory)new RedColorFactory();
aColor color
=factory.Create();
color.ShowColor();
这样,但需求改变的时候,我们只要将具体工厂类的实例化改掉,而不要像上述的那样,把具体new 出颜色的地方都要改;
我们甚至不要改客户代码,就完全可以应付变化,可以通过配置文件的方式,通过反射的来实例化具体事例就可以,这在以前的文章中有具体代码。
这里我们可以通过使用原型模式,避免了额外工厂类的出现。
概述:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。
代码:
抽象类:
  public abstract class aColor
    {
       
       public abstract aColor Clone();
    }
具体实现类:
public class ColorManager:aColor
    {  
        private int _red, _green, _blue;
        public ColorManager(int red, int green, int blue)
        {
            this._red = red;
            this._green = green;
            this._blue = blue;
        }
        public override aColor Clone()
        {
            return (aColor)this.MemberwiseClone();
        }
      
    }


我们的客户程序
 public  class ColorPpalette
    
{
       
       
public void Show()
       
{
           aColor color1 
= new ColorManager(255255255);
           aColor color2 
= new ColorManager(2552550);
           aColor color3 
= new ColorManager(25500);
           
//
           aColor colorA = color1.Clone();
           aColor colorB 
= color2.Clone();
           aColor colorC 
= color3.Clone();
           
       }

    }
这个示例里面没有出现工厂类,其实按我的理解,工厂方法已经和产品类耦合在一起了;那个Clone方法是不是很像我们第一个例子里面的Create方法?
这个例子是个特殊情况,我们只要提供不同的RGB值就可创建出不同的颜色类型,但是一般情况下,我们还是要新增多个不同产品的类,但工厂类我们却可以避免了
但是,在我们进行克隆方法编写的时候,容易出错,需要对类的结构有很好的了解;我们例子中只是进行了浅拷贝,如果碰到非值类型的数据,我们就需要通过序列化和反序列化来进行深拷贝了