《.NET与设计模式》学习(二)

第2篇 设计模式的实现与使用

第六章 简单工厂

        面向接口编程要求针对接口,而不是具体的实现。有一个问题是,尽管编程是面向接口,但执行时的操作需要实例化后的对象,而实例化必须要针对具体的类。若直接实例化,则破坏了面向接口的编程原则。解决的方法就是通过一个专门实例化的类来获得具体的对象,通常将这个类称为“工厂”,将与实例化相关的模式称为“创建型模式”。
1.意图
        简单工厂的作用是实例化对象,而不需要客户了解这个对象属于哪个具体的子类。
2.使用场合
        简单工厂实例化的类具有相同的接口,类类有限并且基本不需要扩展。
3..NET实现
        通常简单工厂不需要实例化,而是采用静态方法。
·抽象类与接口优劣性的讨论:
        如果需要被实例化的子类有大量相同代码,可考虑采用抽象类,可以减少代码的重复。然而这样做的缺点是扩展性不好,子类之间存在潜在的耦合性。因此通常可考虑采用接口代替抽象类。
·代码框架

// 交通工具是一个必须继承的基类
public    abstract   class  Vehicle
{
    
protected   string  m_TypeName;
    
public   string  TypeName
    {
        
get
        {
            
return  m_TypeName;
        }
        
set
        {
            m_TypeName
= Value;
        }
    }
    
public   abstract   string  Go()
}

// 汽车是交通工具的子类
public   class  Car:Vehicle
{
    
public  Car()
    {
        m_TypeName
= " 汽车 " ;
    }
    
public   override   string  Go()
    {
        
return   " 汽车在公路上开 " ;
    }
}

// 火车是交通工具的子类
public   class  Train:Vehicle
{
    
public  Car()
    {
        m_TypeName
= " 火车 " ;
    }
    
public   override   string  Go()
    {
        
return   " 火车在铁轨上开 " ;
    }
}


// 船是交通工具的子类
public   class  Boat:Vehicle
{
    
public  Car()
    {
        m_TypeName
= " " ;
    }
    
public   override   string  Go()
    {
        
return   " 船在水上走 " ;
    }
}

public   class  CreateAVehicle
{
    
// 将创建方法定义为静态
     public   static  Vehicle CreateAVehicle( string  typeid)
    {
        Vehicle v;
        
// 根据参数确定需要创建的对象
          switch (typeid.ToLower())
        {
            
case   " car " :
                  v
= new  Car();
                  
break ;
            
case   " train " :
                  v
= new  Train();
                  
break ;
            
case   " boat " :
                  v
= new  Boat();
                  
break ;
        }
        
return  v;
    }
}
4.应用
        对于数据库类型的不同,可将其统一封装于一个简单工厂中,方便使用及日后的维护。
        对于程序的配置信息的保存位置(如:配置文件,注册表,数据库等),也可用简单工厂封存装。

第七章 工厂方法模式
        工厂方法是粒度很小的设计模式,因为模式的表现只是一个抽象的方法。工厂方法经常用于创建与某个类相关的类的实例。
1.意图
        定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到子类,这个接口所指的是一个抽象方法。该方法说明需要创建一个对象,但并不给出具体的创建方法和创建什么类型的对象。
·代码:
using  System;
namespace  CSharpCreator
{
    
public   abstract   class  Creator
    {    
        
public   abstract  production FactoryMethod();    
    }
    
public   class  ConcreteCreator:Creator
    {
        
public   override  production FactoryMethod()
        {
            
return   new  ConcreteProduction();
        }
    }
}
2.使用场合
        当一个类不知道它所必须创建对象的类或一个类希望由子类来指定它所创建的对象时。
3.应用——获得多媒体播放对象
        希望同一个架构既可以采用RealPlay播放器,也可以用MSMedia Player播放器。
·代码框架(省略了系统自动生成的代码)
public   abstract   class  BasePlayForm:System.Windows.Forms.Form
// 播放器声明为符合AudioPlayer接口
protected  AudioPlayer mmply;
// 工厂方法,在子类中定义具体的播放器
protected   abstract  AudioPlayer GetMP();
// 打开媒体文件
private   void  mnOpen_Click( object  sender, ImageClickEventArgs e)
{
        
if ( this .OpenFileDialog1.ShowDialog == DialogResult.OK)
    {
        mmply
= GetMP();
        mmply.Source
= this .OpenFileDialog.FileName;
    }
}
// 播放
private   void  mnPlay_Click( object  sender, ImageClickEventArgs e)
{
        mmply.DoPlay();
}
// 暂停
private   void  mnPause_Click( object  sender, ImageClickEventArgs e)
{
        mmply.DoPause();
}
// 停止
private   void  mnStop_Click( object  sender, ImageClickEventArgs e)
{
        mmply.DoStop();
}
以下是采用RealPlay和MS Media Player播放器的代码(分别继承自BasePlayForm类)
public   class  PlayMedia:BasePlayForm
{
    
protected   override  AudioPlayer GetMP()
    {
        
return   new  MediaPlayer();
    }
}

public   class  PlayReal:BasePlayForm
{
    
protected   override  AudioPlayer GetMP()
    {
        RealAudioPlayClass c
= new  RealAudioPlayerClass( this );
                
return  c;
    }
}

·工厂方法使类中的代码不依赖于它必须创建的类,代码只要知道它需要创建的类的接口。工厂方法的缺点是新增加一个需要创建的类,就需要增加一个相应的子类。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值