您的位置:首页 > 其它

设计模式 之 抽象工厂

2007-10-11 15:39 966 查看
前一篇文章,介绍了工厂方法,并且,探讨了下工厂方法的不足之处:

及我们知道,在工厂方法中,每个 Creator,只是创建单一的实例,那对于一次要创建n多不同的类实例的情况呢?
及,如果我们要实现这样的方法呢?:
using System;
using System.Collections.Generic;
using System.Text;

namespace 工厂方法
{
public interface ICreator<T> where T : IDomain
{
ISpeciality<T> CreaterSpeciality( );
//这里带上其他的类的创建方法
}
}

抽象工厂,为我们很好的解决了这个问题。

如在一个农场中,会种植水果和蔬菜。而蔬菜和水果的种类,又因地域的不同而不同,如:南方的农民种植的水果为荔枝,蔬菜为苦瓜,北方的农民种植的水果是红枣,蔬菜是大白菜。一个农场的农民,农场主不可能要求他的工人在会种植一样东西,需要都能够种植。用程序来解释,如下:

农民接口:

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

namespace 抽象工厂
{
public interface 农民接口
{
蔬菜接口 种植蔬菜();

水果接口 种植水果();

}
}

水果接口:

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

namespace 抽象工厂
{
/// <summary>
/// 水果的接口
/// </summary>
public interface 水果接口
{
/// <summary>
/// 水果的味道
/// </summary>
/// <returns></returns>
string 味道();
/// <summary>
/// 水果生长周期
/// </summary>
/// <returns></returns>
int 水果生长周期();

/// <summary>
/// 水果生长区域
/// </summary>
/// <returns></returns>
string 生长区域();

}
}

蔬菜接口:

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

namespace 抽象工厂
{
/// <summary>
/// 蔬菜接口
/// </summary>
public interface 蔬菜接口
{
/// <summary>
/// 蔬菜生长区域
/// </summary>
/// <returns></returns>
string 生长区域();

/// <summary>
/// 一棵种子是否只长一个果实
/// </summary>
/// <returns></returns>
bool 一棵种子是否只长一个果实();
}
}

各种水果类:

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

namespace 抽象工厂
{
/// <summary>
/// 荔枝类 南方生产的水果
/// </summary>
public class 荔枝 : 水果接口
{
public string 味道()
{
return "荔枝非常的甜";
}

public int 水果生长周期()
{
return 1;
}
public string 生长区域()
{
return "南方";
}
}
}

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

namespace 抽象工厂
{
public class 红枣 : 水果接口
{
public string 味道()
{
return "红枣有点甜";
}

public int 水果生长周期()
{
return 1;
}
public string 生长区域()
{
return "北方";
}
}
}

各种蔬菜类:

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

namespace 抽象工厂
{
public class 大白菜 : 蔬菜接口
{
public string 生长区域()
{
return "北方";
}

public bool 一棵种子是否只长一个果实()
{
return true;
}
}
}

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

namespace 抽象工厂
{
public class 苦瓜 : 蔬菜接口
{
public string 生长区域()
{
return "南方";
}

public bool 一棵种子是否只长一个果实()
{
return false;
}
}
}

农民类:

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

namespace 抽象工厂
{
public class 南方农民 : 农民接口
{
public 蔬菜接口 种植蔬菜()
{
return new 苦瓜();
}

public 水果接口 种植水果()
{
return new 荔枝();
}
}
}

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

namespace 抽象工厂
{
public class 北方农民 : 农民接口
{
public 蔬菜接口 种植蔬菜()
{
return new 大白菜();
}

public 水果接口 种植水果()
{
return new 红枣();
}
}
}

使用的时候:

private void button1_Click(object sender, EventArgs e)
{
农民接口 一个农民 = new 南方农民();
水果接口 水果 = 一个农民.种植水果();
蔬菜接口 蔬菜 = 一个农民.种植蔬菜();
}

这样,南方的农民就可以同时种植南方的水果和南方的蔬菜了,也就解决了一个农民只能够种植一种东西的情况,也就是解决了工厂方法的问题。

抽象工厂 和 建造者buileder的不同:

首先,抽象工厂返回的是一个完完全全的产品对象,客户端 可以根据这些产品对象,再去组装出更加复杂的产品对象。

而建造者,返回的不是一个完整的产品对象,客户端需要自己在去把产品的各个部件在组装起来。

如果两个模式结合起来用,情况可以这样:

如在一个游戏中,如:西山居 开发的 剑侠情缘 来说,一张地图上,需要建立房子,道路,路标,广告牌等等,

一张地图,需要创建这些东西,而这些房子呀什么的,又有不同的风格,建造者+抽象工厂,就可以能够满足这个地图的创建(呵呵,对于该游戏到底是怎么弄的,我是不知道,自己乱想的)

上面的程序,用的中文表示,呵呵,一是测试vs里面能够用中文不,二是这样看起来容易点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: