工业化生产:简单工厂、工厂方法和抽象工厂模式

假想场景:hp和apple是全球知名的电脑生产厂家,他们各自的电脑操作系统分别是windows和macintosh,microsoft是软件行业的龙头。为了吸引更多客户购买电脑,hp和apple请ms为他们开发两款最常用的软件,办公软件和及时通讯工具。ms结了订单后,分别为hp和apple开发了office和msn。
上面的场景其实蕴含着我们常见的设计模式思维方式,code is cheap,代码来了。
一:简单工厂
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
//ms的产品
public class Software
{
    
private string softwareName;

    
public virtual string SoftwareName
    {
        
get { return softwareName; }
        
set { softwareName = value; }
    }
    
public string GetSoftwareName()
    {
        
return softwareName;
    }
}
//ms的产品:office
public class Office:Software
{
    
public override string GetSoftwareName()
    {
        
this.SoftwareName = "Office";
        
return “Office”;
    }
}
//ms的产品:msn
public class Msn : Software
{
    
public override string GetSoftwareName()
    {
        
this.SoftwareName = "Msn";
        
return “Msn”;
    }
}

/// <summary>
/// 简单工厂
/// </summary>
public class MsSoftwareFactory
{
    
public static Software CreateSoftware(string softwareName)
    {
        Software msSoftware 
= null;
        
switch (softwareName)
        {
            
default:
                
break;
            
case "office":
                msSoftware 
= new Office();
                
break;
            
case "msn":
                msSoftware 
= new Msn();
                
break;
        }
        
return msSoftware;
    }
}



/// <summary>
/// 客户端调用
/// </summary>
public class Client {
    
static void Main(string[] args)
    {
        Software msSoftware 
= MsSoftwareFactory.CreateSoftware("office");
        Console.WriteLine(msSoftware.GetSoftwareName());
    }
}

上面的简单工厂在一个方法体中有个switch...case,违背了“对扩展开放,对修改封闭”的原则,即“开放-封闭原则”。下面的工厂方法就克服了简单工厂的缺点,降低了客户端程序和产品对象的耦合。

二:工厂方法
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
//ms的产品
public class Software
{
    
private string softwareName;

    
public string SoftwareName
    {
        
get { return softwareName; }
        
set { softwareName = value; }
    }
    
public virtual string GetSoftwareName()
    {
        
return softwareName;
    }
}
//ms的产品:office
public class Office:Software
{
    
public override string GetSoftwareName()
    {
        
this.SoftwareName = "Office";
        
return "Office";
    }
}
//ms的产品:msn
public class Msn : Software
{
    
public override string GetSoftwareName()
    {
        
this.SoftwareName = "Msn";
        
return "Msn";
    }
}

interface ISoftwareFactory
{
    Software CreateSoftware();
}

/// <summary>
/// office工厂
/// </summary>
public class OfficeFactory:ISoftwareFactory
{
    
public  Software CreateSoftware()
    {
        
return new Office();
    }
}

/// <summary>
/// msn工厂
/// </summary>
public class MsnFactory : ISoftwareFactory
{
    
public Software CreateSoftware()
    {
        
return new Msn();
    }
}


/// <summary>
/// 客户端调用
/// </summary>
public class Client {
    
static void Main(string[] args)
    {
        ISoftwareFactory factory 
= new OfficeFactory();
        Software msSoftware 
= factory.CreateSoftware();
        Console.WriteLine(msSoftware.GetSoftwareName());
    }
}
工厂方法的缺点是每加一个产品,就要创建一个对应的产品工厂类,增加了额外的开发量。
三、抽象工厂
提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类。
抽象工厂最经典的应用莫过于数据库访问程序。网上有很多这方面的讨论。不多说了。这里我继续用开篇讲的场景来描述。
我们知道office和msn根据操作系统的不同可以分为windows版本的和mac版本的,也许还有linux,unix版本的,归根结底,这里的产品涉及到产品系列的问题,抽象工厂可以解决这个问题:
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;

//ms的产品:office
public class Office
{
    
private string softwareName;

    
public string SoftwareName
    {
        
get { return softwareName; }
        
set { softwareName = value; }
    }
}

public interface IOffice
{
    Office GetOffice();
}

//ms的windows版本Office
public class WinOffice : IOffice
{
    
public Office GetOffice()
    {
        
return new Office();
    }
}

//ms的macintosh版本Office
public class MacOffice : IOffice
{
    
public Office GetOffice()
    {
        
return new Office();
    }
}

//ms的产品:msn
public class Msn 
{
    
private string softwareName;

    
public string SoftwareName
    {
        
get { return softwareName; }
        
set { softwareName = value; }
    }
}

public  interface IMsn
{
    Msn GetMsn();
}

//ms的windows版本msn
public class WinMsn:IMsn
{
    
public Msn GetMsn()
    {
        
return new Msn();
    }
}

//ms的macintosh版本msn
public class MacMsn : IMsn
{
    
public Msn GetMsn()
    {
        
return new Msn();
    }
}

interface ISoftwareFactory
{
    IOffice CreateOffice();
    IMsn CreateMsn();
}

/// <summary>
/// windows版本的工厂
/// </summary>
public class WindowsFactory:ISoftwareFactory
{
    
public IOffice CreateOffice()
    {
        
return new WinOffice();
    }
    
public IMsn CreateMsn()
    {
        
return new WinMsn();
    }
}

/// <summary>
/// macintosh版本的工厂
/// </summary>
public class MacFactory : ISoftwareFactory
{
    
public IOffice CreateOffice()
    {
        
return new MacOffice();
    }
    
public IMsn CreateMsn()
    {
        
return new MacMsn();
    }
}


/// <summary>
/// 客户端调用
/// </summary>
public class Client {
    
static void Main(string[] args)
    {
        ISoftwareFactory factory 
= new WindowsFactory();
        IOffice office 
= factory.CreateOffice();
        IMsn msn 
= factory.CreateMsn();
    }
}

转载于:https://www.cnblogs.com/jeffwongishandsome/archive/2009/03/15/1411621.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值