您的位置:首页 > 其它

面向对象的设计模式系列之二:工厂方法模式(FactoryMethod)

2012-04-03 17:25 633 查看
在上一篇文章中(Singleton设计模式)曾谈到了工厂模式,那究竟什么是工厂模式呢?它又能解决什么样的问题呢?在知晓这个问题之前,让我们先了解一个概念:对象耦合。经常在很多技术书籍上听到"松耦合,高内聚"。那什么是松耦合呢?既然有松耦合,那应该存在相对的紧耦合吧。两者之间到底有什么联系呢?

带着这些问题,我们可以展开为什么需要工厂模式的缘由。松耦合即在软件系统中,模块与模块之间在应对软件变化(主要来自需求变化)时,一些模块很容易被替换或更改,而能使其他模块保持不变。相对的,紧耦合即软件应对变化时,一些软件的改变将会使相关模块发生改变。先看看下面的两幅图:

生产指导者

/// <summary>
/// 生产指导者基类
/// </summary>
public abstract class Director
{
//步骤集合
protected IList<Decision> decisions = new List<Decision>();
//添加决策
public virtual void Insert(Decision decision)
{
if (decision == null || decision.Factory == null || decision.Quantity <= 0)
{
return;
}
decisions.Add(decision);
}
//以便客户端遍历决策集合
public virtual IEnumerable<Decision> Decisions
{
get { return decisions; }
}
}

/// <summary>
/// 视频播放器指导者
/// </summary>
public class VideoPlayerDirector : Director
{
public VideoPlayerDirector()
{
base.Insert(new RealPlayerDecision());
base.Insert(new MSMediaPlayerDecision());
}
//对外加工的入口
public VideoPlayerList Produce()
{
var players = new VideoPlayerList();
foreach (var decision in Decisions)
{
players += decision.Factory.CreateVideoPlayers(decision.Quantity);
}
return players;
}
}


我们建立单元测试:

[TestMethod]
public void TestBatchVideoPlayerFactory()
{
var director = new VideoPlayerDirector();
var players = director.Produce();//开始加工
Assert.AreEqual<int>(3000 + 2000, players.Count);
//验证前3000个播放器是RealPlayer
for (var i = 0; i < 3000; i++)
{
Assert.IsTrue(players.Items[i].GetType() == typeof(RealPlayer));
}
//验证后2000个播放器是MSMediaPlayer
for (var i = 3000; i < 5000; i++)
{
Assert.IsTrue(players.Items[i].GetType() == typeof(MSMediaPlayer));
}
}


到现在为止,利用工厂方法模式来面对简单工厂遇到的棘手问题都一一解决了。其实工厂模式是应对"某个对象"的创建工作,且该对象的子类无法在提前预知,能动态添加新类型和创建工厂而不影响其他子类的创建。朋友们也可以想一下如果我创建的实例有多个品牌以及多个型号(比如一个电脑主板可能来自惠普,也可能来自IBM,同时主板可能又有很多型号),又将实例从横向拉到纵向甚至多向,如果要解决这种多维度的对象创建工作,将会利用工厂模式创建其中的一部分维度,并组合成抽象工厂模式来解决。我会再下次讲解抽象工厂时详细解释,这里将本篇所需要的源代码提供以便参考。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: