zoukankan      html  css  js  c++  java
  • 不一样的工厂模式(设计模式六)

    前言

    介绍工厂模式,展示工厂模式的演化。

    正文

    看下工厂模式是如何演化的。

    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 模式用于隔离对象的使用者和具体类型之间耦合关系。通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展,较好的解决了这种紧耦合关系。缺点在于创建方法和参数相同,方法倒是好事,参数倒是一个硬要求。

  • 相关阅读:
    JS获取URL中参数值(QueryString)的4种方法
    js 字符串转换成数字的 三种方法
    jquery.cookie 介绍 和 用法
    JS的document.all函数使用 示例
    JS按回车键实现登录的三种方法
    js 字符串转换成数字的三种方法
    GitHub访问速度慢的一种优化方法
    git commit 提交的时候报错husky > pre-commit hook failed (add --no-verify to bypass)
    git回退
    git commit 提交的时候报错husky > pre-commit hook failed (add --no-verify to bypass)(解决办法)
  • 原文地址:https://www.cnblogs.com/aoximin/p/12113482.html
Copyright © 2011-2022 走看看