zoukankan      html  css  js  c++  java
  • 工厂模式记录

    工厂模式

    工厂模式分为3种,简单工厂,工厂方法模式,抽象工厂模式

    目的都是为了解决客户端在使用类的时候强耦合性。

    简单工厂模式

    简单工厂模式是最简单的工厂模式,里面只用关注工厂就行了,工厂里面加工所有一类东西,通过流式选择选择加工的东西
    我们以水果作为例子进行记录
    工厂:

    /// <summary>
        /// 生产水果,但是不让外界知道细节
        /// </summary>
        class SimplyFactory
        {
            public Fruit CreatFruit(string name)
            {
                switch (name) 
                {
                    case "apple":return new Apple(name);
                    case "pear": return new Pear(name);
                    default:return new Otherfruits();
                }
            }
        }
    

    生产对象:apple和pear

        class Apple:Fruit
        {
            public Apple(string Name)
            {
                this.Name = Name;
            }
            public string Name { get; set; }
        }
    
        class Pear:Fruit
        {
            public Pear(string Name)
            {
                this.Name = Name;
            }
            public string Name { get; set; }
        }
    

    使用者:

            public void eat() {
                Fruit apple = new SimplyFactory().CreatFruit("apple");
                Fruit pear = new SimplyFactory().CreatFruit("pear");
                Console.WriteLine(apple.Name);
                Console.WriteLine(pear.Name);
            }
    

    这里使用简单工厂不仅只限于解耦合,而且在使用中对生产的apple或者pear有要求时,只需要修改工厂就好了,不用像直接调用那样,每个调用的地方都要修改。
    这就是简单工厂模式,但是在应用中会发现简单工厂模式的不足。

    • 就是对于扩展来说,我们需要修改工厂的内部,我们违反开闭原则
    • 工厂中不能责任单一,我们违反了责任单一原则
      所以需要对这个简单工厂模式修改,要保证上面原则的实现,如何修改能保证开闭原则责任单一原则
      我们需要针对这个工程进行分析开闭原则,可以将工厂分开,让apple工厂和pear工厂...等等分开,这样不就实现了开闭原则,仔细想下同时实现
      责任单一原则
      将工厂分开就是所谓的工厂方法模式
      apple:
      class AppleFactory
        {
            public Fruit creatFruit(string name) 
            {
                return new Apple(name);
            }
        }
    

    pear:

     class PearFactory
        {
            public Fruit creatFruit(string name)
            {
                return new Pear(name);
            }
        }
    
        class User
        {
            public void eat() 
            {
                Fruit apple = new AppleFactory().creatFruit("apple");
                Fruit pear = new PearFactory().creatFruit("pear");
                Console.WriteLine(apple + "---"+pear);
            }
        }
    

    分析下上面的工厂方法模式,发现这个写法好像耦合性不仅没有降低而且耦合中还夹杂了工厂,感觉不如直接调用简单,这个感觉是没错的,因为工厂
    的规模比较小,如果生产是个复杂的系统,才能体现出他的优势。
    分析下现在的开闭原则责任单一原则

    • 符合开闭原则,因为他在扩展桃、杏等水果时,不需要再对工厂进行修改了,值用增加新的子类工厂就好了
    • 符合责任单一原则,因为每个工厂只负责本身事件的生产。
      工厂方法模式的问题是将实例类型交给了客户端,这样就需要对这个类型进行抽象(我的代码式样不能展示出抽象
      的好处,试想下一个场景,在传递的过程中我能将传参里面写了具体的工厂类AppleFactory或者写了抽象的工厂类
      AbstractMethodFactory这两个区别,后面的在项目的迭代过程中更有优势,因为项目迭代过程中能保证你传递参数
      类的开闭原则,并且减少你代码修改,提高系统的健壮性)

    抽象工厂模式

    将工厂抽象化在实现就是所谓的抽象工厂模式
    抽象工厂:

        /// <summary>
        /// 建立抽象工厂
        /// </summary>
        abstract class AbstractMethodFactory
        {
            abstract public Fruit CreatFruit(string name);
        }
    

    apple工厂:

        class AppleFactory : AbstractMethodFactory
        {
            public override Fruit CreatFruit(string name)
            {
                return new Apple(name);
            }
        }
    

    pear工厂:

        class PearFactory : AbstractMethodFactory
        {
            public override Fruit CreatFruit(string name)
            {
                return new Pear(name);
            }
        }
    

    使用者:

        class User
        {
            public void eat() 
            {
                Fruit apple = new AppleFactory().CreatFruit("apple");
                Console.WriteLine(apple.Name);
                Fruit pear = new PearFactory().CreatFruit("pear");
                Console.WriteLine(pear.Name);
            }
        }
    

    抽闲工厂模式很好的实现了依赖倒置原则,细节依赖于抽象,会将细节隐藏到抽象下,并且实体工厂时很方便
    但是缺点也比较明显。如果工厂有其他的产品增加,就需要增加抽象里的抽象方法,并且之前的工厂子类也要修改
    (这里使用的是抽象可以不用去修改子类),这里我写的不规范这里应该使用interface,修改了就违反了开闭原则,并且在扩展后
    需要将之前的子类都要添加这个方法,所以这个抽象工厂模式适合稳定的生产线(不增加产品功能,只增加产品的类型)。

  • 相关阅读:
    SecureCRT8.3
    firewalld
    yum的repo文件详解、以及epel简介、yum源的更换、常用yum命令
    Softether使用本地网桥
    nginx应用geoip模块,实现不同地区访问不同页面的需求(实践版)
    iOS开发>学无止境
    iOS开发>学无止境
    iOS开发>学无止境
    iOS开发>学无止境
    Objective-C学习- appDelegate 生命周期
  • 原文地址:https://www.cnblogs.com/liuyang95/p/13367395.html
Copyright © 2011-2022 走看看