不一样的工厂模式(设计模式六)
前言
介绍工厂模式,展示工厂模式的演化。
正文
看下工厂模式是如何演化的。
public interface ISplitter
{
void Splite();
}
class BinarySplitter : ISplitter
{
public void Splite()
{
throw new NotImplementedException();
}
}
class TxtSplitter : ISplitter
{
public void Splite()
{
throw new NotImplementedException();
}
}
class VideoSplitter : ISplitter
{
public void Splite()
{
throw new NotImplementedException();
}
}
假如有上面这些东西,分别是字节切割、文本切割、声音切割。
然后有一个类调用:
public class Application
{
public void doSomeThing()
{
ISplitter splitter = new TxtSplitter();
}
}
那么问题来了,这样写好不好?
答案是不好,因为违反了依赖倒置原则。
依赖倒置原则(Dependence Inversion Principle)是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
new TxtSplitter() 依赖了具体的实现了,所以不符合。
那么既然不能依赖具体的类,那么如何获取到TxtSplitter 对象呢?
既然不能依赖于类,那么可以用方法返回。
class SplitterFactory
{
public static ISplitter CreateSplitter()
{
return new BinarySplitter();
}
}
好吧。
然后:
ISplitter splitter = SplitterFactory.CreateSplitter();
看这一行:ISplitter splitter = SplitterFactory.CreateSplitter();
splitter 是接口没有依赖具体的实现,BinaryFactory.CreateSplitter()也没有直接依赖具体的实现。
SplitterFactory.CreateSplitter()怎么能说没有直接依赖具体的实现呢?这个怎么看呢?要从当前类Application来看,从Application来看,显示创建一个SplitterFactory.CreateSplitter()
Application是不知道到底SplitterFactory.CreateSplitter() 创建了什么,只有SplitterFactory知道。所以在Application没有直接依赖具体实现。
但是问题就是application 没有直接具体依赖,但是却有间接具体依赖。
虽然在Application中解决了,但是在SplitterFactory还是有依赖BinarySplitter,这样就形成了间接依赖。
就是这样的。
这样又一个什么坏处呢?现在不用去修改Application 的代码了,因为抽象的,但是如果现在和Application 模型相同的,然后需要用到TxtSplitter。
那么模型就是这样的。
也就是说SplitterFactory的不稳定性导致了,导致了Application 复用性不行,增加了耦合。
那么可以这样:
public abstract class SplitterFactory
{
public abstract ISplitter CreateSplitter();
}
现在就不依赖任何东西了。
那么这样具体的工厂就要具体去实现。
class BinarySplitterFactory : SplitterFactory
{
public override ISplitter CreateSplitter()
{
return new BinarySplitter();
}
}
class TxtSplitterFactory : SplitterFactory
{
public override ISplitter CreateSplitter()
{
return new TxtSplitter();
}
}
class VideoSplitterFactory : SplitterFactory
{
public override ISplitter CreateSplitter()
{
return new VideoSplitter();
}
}
然后Application 这样写:
public class Application
{
SplitterFactory factory;
public Application(SplitterFactory factory)
{
this.factory = factory;
}
public void doSomeThing()
{
ISplitter splitter = factory.CreateSplitter();
}
}
这样子,下图就形成了稳定的。
干了这么多其实就是为了Application的稳定性。
概念图
工厂模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。
Factory Methor 模式用于隔离对象的使用者和具体类型之间耦合关系。通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展,较好的解决了这种紧耦合关系。缺点在于创建方法和参数相同,方法倒是好事,参数倒是一个硬要求。