无废话C#设计模式之三:Abstract Factory

意图
 
       提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
 
场景
 
       还是上次说的那个网络游戏,定下来是一个休闲的 FPS游戏。和CS差不多,8到16个玩家在游戏里面分成2组对战射击。现在要实现初始化场景的工作。要呈现一个三维物体一般两个元素是少不了的,一是这个物体的骨架,也就是模型,二就是这个骨架上填充的纹理。
       我们知道,这样的一个游戏不可能只有一张地图,而且地图的数量肯定是会一直增加的。如果游戏在初始化场景的时候需要根据不同的地图分别加载模型和纹理对象,那么势必就会使得场景的扩充变得很不方便。由此,我们引入 Abstract Factory,抽象工厂生产的都是实际类型的接口(或者抽象类型),如果加了新的场景可以确保不需要修改加载场景的那部分代码。
 
示例代码
using  System;

using  System.Reflection;

 

namespace  AbstractFactoryExample

{

    
class Program

    
{

        
static void Main(string[] args)

        
{

            Patrix patrix 
= new Patrix();

            patrix.LoadScene(
"HalfPaper");

            patrix.LoadScene(
"Matrix");

        }


    }


 

    
class Patrix

    
{

        
private PatrixSceneFactory GetGameScene(string gameSceneName)

        
{

            
return (PatrixSceneFactory)Assembly.Load("AbstractFactoryExample").CreateInstance("AbstractFactoryExample." + gameSceneName);

        }


 

        
public void LoadScene(string gameSceneName)

        
{

            PatrixSceneFactory psf 
= GetGameScene(gameSceneName);

            Texture texture 
= psf.CreateTexture();

            Model model 
= psf.CreateModel();

            model.FillTexture(texture);

        }


    }


 

    
abstract class PatrixSceneFactory

    
{

        
public abstract Model CreateModel();

 

        
public abstract Texture CreateTexture();

    }


 

    
abstract class Model

    
{

        
public abstract void FillTexture(Texture texture);

    }


 

    
abstract class Texture

    
{

 

    }


 

    
class HalfPaper : PatrixSceneFactory

    
{

        
public override Model CreateModel()

        
{

            
return new HalfPaperModel();

        }


 

        
public override Texture CreateTexture()

        
{

            
return new HalfPaperTexture();

        }


    }


 

    
class HalfPaperModel : Model

    
{

        
public HalfPaperModel()

        
{

            Console.WriteLine(
"HalfPaper Model Created");

        }


 

        
public override void FillTexture(Texture texture)

        
{

            Console.WriteLine(
"HalfPaper Model is filled Texture");

        }


    }


 

    
class HalfPaperTexture : Texture

    
{

        
public HalfPaperTexture()

        
{

            Console.WriteLine(
"HalfPaper Texture Created");

        }


    }


 

    
class Matrix : PatrixSceneFactory

    
{

        
public override Model CreateModel()

        
{

            
return new MatrixModel();

        }


 

        
public override Texture CreateTexture()

        
{

            
return new MatrixTexture();

        }


    }


 

    
class MatrixModel : Model

    
{

        
public MatrixModel()

        
{

            Console.WriteLine(
"Matrix Model Created");

        }


 

        
public override void FillTexture(Texture texture)

        
{

            Console.WriteLine(
"Matrix Model is filled Texture");

        }


    }


 

    
class MatrixTexture : Texture

    
{

        
public MatrixTexture()

        
{

            Console.WriteLine(
"Matrix Texture Created");

        }


    }


}

 
代码说明
 
l         PatrixSceneFactory就是一个抽象工厂,它声明了创建抽象的场景以及抽象的纹理的接口。(广告时间: Patrix是我公司的一款休闲FPS游戏,详细请见http://www.qwd1.com
l         Model和 Texture是抽象产品。在Model类中有一个抽象方法,用于为模型填充纹理。
l         HalfPaper和 Matrix是具体工厂,它用于创建某个场景的模型和纹理。(你可能对两个类的名字不太理解,其实HalfPaper和Matrix是两个地图的名字)
l         xxxModel和 xxxTexture就是具体的产品了。它们就是针对某个场景的模型和纹理,具体工厂负责创建它们。
l         Patrix这个类负责加载场景,为了避免加载不同场景使用 case语句,在这里我们使用反射来加载具体工厂类。
l         可以看到,一旦有了新的场景(或者说地图),我们只需要设计新的 xxxModel和xxxTexture以及具体工厂类就可以了,加载场景的那部分代码(也就是Patrix类)不需要做改动。
l         我们现在这个游戏可是不支持和电脑对战的,万一以后需要支持电脑了,那么场景中的元素除了纹理和模型之外就还需要加电脑了。也就是说抽象工厂还需要多生产一种类型的产品,这个时候抽象工厂就无能为力了。抽象工厂只能解决系列产品扩张的变化点(在我们的例子中就是地图的新增),因此千万把抽象工厂所能生产的产品考虑周全了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值