设计模式之:简单工厂模式、工厂方法模式、抽象工厂模式

一、简单工厂模式(Simple Factory Pattern)
简单工厂模式又称为静态工厂方法(Static Factory Method)模式,通常根据一个条件(参数)来返回不同的类的实例。
严格地来说,它不是一种设计模式,而是一种编程习惯。
示例代码:
public interface ICoat
{
    void GetYourCoat();
}

namespace SimpleFactory
{
    public class BusinessCoat:ICoat
    {
        public void GetYourCoat()
        {
            Console.WriteLine("商务上衣");
        }
    }

    public class FashionCoat : ICoat
    {
        public void GetYourCoat()
        {
            Console.WriteLine("时尚上衣");
        }
    }
}

namespace SimpleFactory
{
    /// <summary>
    /// 简单工厂模式中的核心部分:工厂类
    /// </summary>
    public class Factory
    {
        public ICoat CreateCoat(string styleName)
        {
            switch (styleName.Trim().ToLower())
            {
                case "business":
                    return new BusinessCoat();
                case "fashion":
                    return new FashionCoat();
                default :
                    throw new Exception("还没有你要的那种衣服");
            }
        }
    }
}

/// <summary>
/// 客户端调用
/// </summary>
class Client
{
    static void Main(string[] args)
    {
        ICoat food;
        try
        {
            Factory factory = new Factory();
            Console.Write("我要的是时尚上衣\t");
            food = factory.CreateCoat("fashion");
            food.GetYourCoat();

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

二、工厂方法模式(Factory Method Pattern)
工厂方法模式又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂模式(Polymorphic Factory),在工厂方法模式中,父类负责定义创建对象的公共接口,而子类则负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成。
一个工厂类只负责一个对象实例的创建,即工厂类与对象实例之间是一一对应的关系。
示例代码:
namespace FactoryMethod
{
    /// <summary>
    /// 抽象工厂类,定义产品的接口
    /// </summary>
    public interface IFactory
    {
     ICoat CreateCoat();
    }
}

namespace FactoryMethod
{
    /// <summary>
    /// 抽象产品类
    /// </summary>
    public interface ICoat
    {
        void ShowCoat();
    }
}

具体工厂角色代码
namespace FactoryMethod
{
    /// <summary>
    /// 具体工厂类:用于创建商务上衣类
    /// </summary>
    public class BusinessFactory:IFactory
    {       
        public ICoat CreateCoat()
        {
            return new BusinessCoat();
        }
    }

    /// <summary>
    /// 具体工厂类,用于创建时尚上衣
    /// </summary>
    public class FashionFactory : IFactory
    {
        public ICoat CreateCoat()
        {
            return new FashionCoat();
        }
    }
}

namespace FactoryMethod
{
    /// <summary>
    /// 具体产品类,商务上衣类
    /// </summary>
    public class BusinessCoat:ICoat
    {
        public void ShowCoat()
        {
            Console.WriteLine("这件是商务上衣");
        }
    }

    /// <summary>
    /// 具体产品类,时尚上衣类
    /// </summary>
    public class FashionCoat : ICoat
    {
        public void ShowCoat()
        {
            Console.WriteLine("这件是时尚上衣");
        }
    }
}

namespace FactoryMethod
{
    /// <summary>
    /// 客户端代码
    /// </summary>
    class Client
    {
        static void Main(string[] args)
        {
            //为了方便以后修改,将工厂类的类名写在应用程序配置文件中
            string factoryName = ConfigurationManager.AppSettings["FactoryName"];
            IFactory factory = (IFactory)Assembly.Load("ConcreteFactory").CreateInstance("FactoryMethod." + factoryName);
            ICoat coat = factory.CreateCoat();
            //显示你要的上衣
            coat.ShowCoat();
        }
    }
}

三、抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式管理的是一系列相关或相互依赖对象的创建。
GOF认为,抽象工厂模式“提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。”这里所谓的相关或相互依赖指的是:要求这些对象具有相同的继承体系,并因此而形成一个产品族(Product Family)。
示例代码:
//抽象工厂角色:
namespace AbstractFactory
{
    //抽象工厂类,
    public abstract class AbstractClothes
    {
        //抽象方法:创建一个上衣
        abstract public AbstractCoat CreateCoat();
        //抽象方法:创建一个裤子
        abstract public AbstractTrousers CreateTrousers();
    }
}

//抽象产品角色:
namespace AbstractFactory
{
    /// <summary>
    /// 抽象产品----上衣抽象类
    /// </summary>
    public abstract class AbstractCoat
    {
        //性别属性
        public abstract bool Sex
        {
            get;
        }

        //样式属性
        public abstract string Style
        {
            get;
        }
    }

    /// <summary>
    /// 抽象产品----裤子抽象类
    /// </summary>
    public abstract class AbstractTrousers
    {
        //性别属性
        public abstract bool Sex
        {
           get;
        }

        //样式属性
        public abstract string Style
        {
            get;
        }
    }
}

//具体工厂角色:
namespace AbstractFactory
{
    /// <summary>
    ///时尚男装
    /// </summary>
    public class FashionManClothes:AbstractClothes
    {
        public override AbstractFactory.AbstractCoat CreateCoat()
        {
            return new CoatA();
        }

        public override AbstractTrousers CreateTrousers()
        {
            return new TrousersA();
        }
    }

    /// <summary>
    /// 时尚女装
    /// </summary>
    public class FashionWomanClothes : AbstractClothes
    {
        public override AbstractCoat CreateCoat()
        {
            return new CoatB();
        }
        public override AbstractTrousers CreateTrousers()
        {
            return new TrousersB();
        }
    }
}

//具体产品角色
namespace AbstractFactory
{
    /// <summary>
    /// 时尚男性上衣
    /// </summary>
    public class CoatA:AbstractFactory.AbstractCoat
    {
        private bool sex = true;
        private string style = "时尚";
        /// <summary>
        /// 重写基类的Sex属性
        /// </summary>
        public override bool Sex
        {
            get
            {
                return sex;
            }           
        }
       
        /// <summary>
        /// 重写基类的Style属性
        /// </summary>
        public override string Style
        {
            get
            {
                return style;
            }           
        }
    }

    /// <summary>
    /// 时尚男性裤子
    /// </summary>
    public class TrousersA : AbstractTrousers
    {
        private bool sex = true;
        private string style = "时尚";
        public override bool Sex
        {
            get
            {
                return sex;
            }
        }
        public override string Style
        {
            get
            {
                return style;
            }
        }
    }
}

//客户端代码:
namespace AbstractFactory
{
    /// <summary>
    /// 创建衣服类
    /// </summary>
    public class CreateClothes
    {
        private AbstractCoat myCoat;
        private AbstractTrousers myTrousers;
        public CreateClothes(AbstractClothes clothes)
        {
            myCoat = clothes.CreateCoat();
            myTrousers = clothes.CreateTrousers();
        }

        public void ShowMyClothes()
        {
            Console.WriteLine("My Clothes:");
            string sex= myCoat.Sex ? "男" : "女";
            Console.WriteLine("Coat:{0} {1}", sex, myCoat.Style);
            sex=myTrousers.Sex?"男":"女";
            Console.WriteLine("Trousers:{0} {1}", sex, myTrousers.Style);
        }
    } 
   
    public class Client
    {
        static void Main(string[] args)
        {
            //创建一个工厂类的实例  
            string assemblyName = ConfigurationManager.AppSettings["assemblyName"];
            string fullTypeName =string.Concat( ConfigurationManager.AppSettings["nameSpaceName"] ,".", ConfigurationManager.AppSettings["typename"]);

            AbstractClothes factory = (AbstractClothes)Assembly.Load(assemblyName).CreateInstance(fullTypeName);
            CreateClothes clothes = new CreateClothes(factory);
            clothes.ShowMyClothes();
            Console.Read();
        }       
    }
}

//app.config文件
<configuration>
  <appSettings>
    <!--一般情况下只需改第三个"typename"就行了,具体工厂类    -->
    <add key="assemblyName" value="ConcreteFactory"/>
    <add key="nameSpaceName" value="AbstractFactory"/>
    <add key="typename" value="FashionManClothes"/>
  </appSettings>
</configuration>

本文所引用和摘录的资料来源:
http://www.cnblogs.com/anlyren/archive/2008/01/25/simple_Factory_Pattern.html
http://www.cnblogs.com/yinxiangpei/articles/2366092.html
http://www.cnblogs.com/anlyren/archive/2008/01/31/abstract_factory.html

posted @   skybirdzw  阅读(128)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示