现在的位置: 首页 > 综合 > 正文

DOTA版设计模式——抽象工厂

2013年04月22日 ⁄ 综合 ⁄ 共 4179字 ⁄ 字号 评论关闭
 抽象工厂模式即工厂方法模式的集合。工厂方法得到一种产品,而抽象工厂模式得到一系列产品。
同样先来UML来个总体认识:

一、抽象工厂类
抽象工厂是GameFactory,它生产两种产品(英雄,建筑。当然包括更多,本文只给出两种)。
    /// <summary>
    
/// 抽象工厂
    
/// </summary>
    public abstract class GameFactory
    {
        
public abstract Hero CreateHero();
        
public abstract Environment CreateEnvironment();
    }

上面说到抽象工厂实际是工厂方法的集合,简单来说就是有N个方法。本例中就是创建英雄和建筑的两个方法:
public abstract Hero CreateHero();
public abstract Environment CreateEnvironment();
二、实际的工厂(WarFactory,DotaFactory
具体方法的实现由子类负责。我们现在有两种工厂,一种是纯血统的War对战,另一种是RPG地图Dota,于是乎有了两个实际工厂:
/// <summary>
    
/// 魔兽争霸工厂
    
/// </summary>
    public class WarFactory : GameFactory
    {
        
public override Hero CreateHero()
        {
            
return new BladeMaster();
        }

        public override Environment CreateEnvironment()
        {
            
return new Pubs();
        }
    }

    /// <summary>
    
/// Dota工厂
    
/// </summary>
    public class DotaFactory : GameFactory
    {
        
public override Hero CreateHero()
        {
            
return new Naix();
        }
        
public override Environment CreateEnvironment()
        {
            
return new Altar();
        }
    }

可以看到两个工厂的产品并不一样。
War对战地图上英雄是从祭坛中走出来的,而在Dota里英雄是从小酒馆里买来的,所以WarFactory生产的建筑是“祭坛”,DotaFactory生产的建筑是“小酒馆”。
War对战地图中食尸鬼只是一般兵种,而在Dota中则化为变态的英雄,所以WarFactory生产的英雄是剑圣,DotaFactory生产的英雄是“食尸鬼”。
总之工厂方法和抽象工厂的区别就在工厂方法创建的是单一的产品,而抽象工厂创建的是一系列产品,比如本例中的英雄和建筑等,正是这一系列“产品”构建了我们的“魔兽”世界。
测试代码:
            LandpyForm.Form.OutputResult("War");
            DotaPatternLibrary.AbstractFactory.GameFactory gameFactory = new DotaPatternLibrary.AbstractFactory.WarFactory();
            DotaPatternLibrary.AbstractFactory.Hero hero = gameFactory.CreateHero();
            DotaPatternLibrary.AbstractFactory.Environment environment = gameFactory.CreateEnvironment();
            LandpyForm.Form.OutputResult(hero.Name);
            LandpyForm.Form.OutputResult(environment.Name);
            LandpyForm.Form.OutputResult("Dota");
            gameFactory = new DotaPatternLibrary.AbstractFactory.DotaFactory();
            hero = gameFactory.CreateHero();
            environment = gameFactory.CreateEnvironment();
            LandpyForm.Form.OutputResult(hero.Name);
            LandpyForm.Form.OutputResult(environment.Name);
完整代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using DotaCommon;
using DotaPatternLibrary.Attribute;

namespace DotaPatternLibrary.AbstractFactory
{
    
/// <summary>
    
/// 抽象工厂
    
/// </summary>
    public abstract class GameFactory
    {
        
public abstract Hero CreateHero();
        
public abstract Environment CreateEnvironment();
    }

    /// <summary>
    
/// 魔兽争霸工厂
    
/// </summary>
    public class WarFactory : GameFactory
    {
        
public override Hero CreateHero()
        {
            
return new BladeMaster();
        }

        public override Environment CreateEnvironment()
        {
            
return new Pubs();
        }
    }

    /// <summary>
    
/// Dota工厂
    
/// </summary>
    public class DotaFactory : GameFactory
    {
        
public override Hero CreateHero()
        {
            
return new Naix();
        }
        
public override Environment CreateEnvironment()
        {
            
return new Altar();
        }
    }

    /// <summary>
    
/// 英雄
    
/// </summary>
    public abstract class Hero
    {
        
protected string _name;
        
public string Name
        {
            
get { return _name; }
        }
    }

    /// <summary>
    
/// 剑圣
    
/// </summary>
    internal class BladeMaster : Hero
    {
        
public BladeMaster()
        {
            _name 
= "BladeMaster";
        }
    }

    /// <summary>
    
/// 食尸鬼
    
/// </summary>
    internal class Naix : Hero
    {
        
public Naix()
        {
            _name 
= "Naix";
        }
    }

    /// <summary>
    
/// 环境(建筑)
    
/// </summary>
    public abstract class Environment
    {
        
protected string _name;
        
public string Name
        {
            
get { return _name; }
        }
    }
    
/// <summary>
    
/// 小酒馆
    
/// </summary>
    internal class Pubs : Environment
    {
        
public Pubs()
        {
            _name 
= "Pubs";
        }
    }

    /// <summary>
    
/// 祭坛
    
/// </summary>
    internal class Altar : Environment
    {
        
public Altar()
        {
            _name 
= "Altar";
        }
    }
}

抱歉!评论已关闭.