zoukankan      html  css  js  c++  java
  • 抽象工厂

    先来理解一下抽象类这个概念吧,声明方法的存在而不去实现它的类被叫做抽像类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽像类,并让它指向具体子类的一个实例。不能有抽像构造函数或抽像静态方法。Abstract 类的子类为它们父类中的所有抽像方法提供实现,否则它们也是抽像类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法,也就是抽象类中的方法只能在继承它的子类中实现。

    工厂模式的简单工厂模式在这里就不细说了,首先简述简单工厂的内聚性,在软件产品设计上我们力求“高内聚低耦合”,内聚:就是一个模块内各个元素彼此结合的紧密程度,高内聚就是一个模块内各个元素彼此结合的紧密程度高。耦合:就是一个软件结构内不同模块之间互连程度的度量(耦合性也叫块间联系。指软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密,其耦合性就越强,模块的独立性则越差,模块间耦合的高低取决于模块间接口的复杂性,调用的方式以及传递的信息。简单工厂的耦合度是很低的,因为工厂相互独立,但是从内聚性上看,在工厂类数量很大时要实例一个工厂类就很费劲了,可能存在一堆的判断,内聚性低;其次简单工厂不能满足开闭原则,概念:OCP(开闭原则,Open-Closed Principle):一个软件的实体应当对扩展开放,对修改关闭。大概意思就是对于一个已有的软件,如果需要扩展,应当在不需修改已有代码的基础上进行,简单工厂在增加新的工厂类时,是一定要修改代码的,最少是加一个判断。针对简单工厂的弱点,大神们探索出了抽象工厂模式,下面我来做一个简单的抽象工厂模型,大家一同学习。

    题目是:现在某商场正在做促销,商品打折,衣服打4折,衣服的原价是100元,求买一件衣服多少钱?

    哈哈,这是不是太简单了,简单就简单吧,有代表性就行了,现在商场里的裤子也打折了,裤子打2折,原价也是100元,求买一条裤子和一件衣服多少钱?但此时商店里面的帽子、皮包、鞋子、袜子、妹子什么的也降价了,哈哈,这下不好搞了,有点复杂了,如果我们用简单工厂的话,我们就不得不修改代码了,因为需要判断当前要买的是什么,需要实例哪个类,等东西多到让你烦的时候,你就会觉得我加进去新的东西不就行了吗,非得让我去修改原来的代码干嘛,烦死了,这就是简单工厂不能满足OCP的原则的最好例证,让我们一起把这个烦人的重复写判断的过程省掉。

    以下的代码用的是c#语言,将问题拆解,商品同有两个属性是打几折和原价,为此我们建立两个抽象类分别是:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace shejimoshijihe.抽象工厂
    {
        /// <summary>
        /// 原价
        /// </summary>
        public abstract class yuanjia
        {
            public abstract double Calculate();
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace shejimoshijihe.抽象工厂
    {
        /// <summary>
        /// 打几折
        /// </summary>
        public abstract class daze
        {
            public abstract double Calculate();
        }
    }

    现在我们开始建造工厂,首先是衣服的如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace shejimoshijihe.抽象工厂
    {
        public class yifudaze:daze
        {
            public override double Calculate()
            {
                return  0.4;//衣服4折
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace shejimoshijihe.抽象工厂
    {
        public class yifuyuanjia : yuanjia
        {
            public override double Calculate()
            {
                return 100;//衣服原价100
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace shejimoshijihe.抽象工厂
    {
        public class yifuFactory:AbstractFactory
        {
            public override daze Createdaze()
            {
                return new yifudaze();
            }
            public override yuanjia Createyuanjia()
            {
                return new yifuyuanjia();
            }
        }
    }

    现在来建裤子工厂

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace shejimoshijihe.抽象工厂
    {
        public class kuzidaze:daze
        {
            public override double Calculate()
            {
                return  0.2;//裤子2折
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace shejimoshijihe.抽象工厂
    {
        class kuziyuanjia:yuanjia
        {
            public override double Calculate()
            {
                return 100;//裤子原价100
            }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace shejimoshijihe.抽象工厂
    {
       public class kuziFactory:AbstractFactory
        {
           public override daze Createdaze()
           {
               return new kuzidaze();
           }
           public override yuanjia Createyuanjia()
           {
               return new kuziyuanjia();
           }
        }
    }

    从上面的两个工厂的建造来看,我们看到了一个AbstractFactory类,衣服和裤子的工厂都继承于它,可能大家也想到了它是这个抽象工厂模式的核心了,是的,如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    
    namespace shejimoshijihe.抽象工厂
    {
        public abstract class AbstractFactory
        {
            public abstract yuanjia Createyuanjia();
    
            public abstract daze Createdaze();
        }
    }

    此处就是抽象工厂高内聚的所在了,我们看到衣服和裤子的工厂里都有关于Createyuanjia()和Createdaze()的实现,好了,到此我们就算加再多的商品都不用担心了去修改简单工厂里if(kuzi)else if(yifu)else if(meizi)判断了,现在我们只管添加新的商品工厂就行了,问题又来了,我们怎么取代那个判断呢,我们可以利用反射原理来获得,你现在输入商品的对应的是哪个工厂,我做的是一个窗体:如下

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Reflection;
    
    namespace shejimoshijihe.抽象工厂
    {
        public partial class CHOUXIANGGCANG : Form
        {
            public CHOUXIANGGCANG()
            {
                InitializeComponent();
            }
    
             double num= 0;
            private void button1_Click(object sender, EventArgs e)
            {
                if (!string.IsNullOrEmpty(comboBox1.Text))
                {
                    Assembly assembly = Assembly.GetExecutingAssembly(); //反射获取当前程序集 
                    object obj = assembly.CreateInstance("shejimoshijihe.抽象工厂." + comboBox1.Text);//comboBox1.Text的值是工厂的名,作为开发者获取他是没问题的
                    AbstractFactory ab = (AbstractFactory)obj;
                    //(AbstractFactory)obj.Createyuanjia().Calculate();
                    //(AbstractFactory)obj.Createdaze().Calculate();
                    double yfyuanjia = ab.Createyuanjia().Calculate();
                    double yifudaze = ab.Createdaze().Calculate();
                    double jiage = yfyuanjia * yifudaze;
                    num += jiage;
                    this.label1.Text ="一共"+ num.ToString();
                }
            }
        }
    }

    好了,我们现在算是把它搭建完毕了。剩下的事就是你需要加东西了,需要加什么你就加一个工厂就行了,抽象工厂解决了简单工厂的内聚问题,同时增加了可扩展性,当然简单工厂在一般情况下还是很好用的,不如业务不多的时候,代码会很清晰易懂。博主不善于画图,逻辑结构图可到网上查阅。

  • 相关阅读:
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    C语言基础知识【作用域规则】
  • 原文地址:https://www.cnblogs.com/ouzining/p/4174495.html
Copyright © 2011-2022 走看看