设计模式之:简单工厂模式、工厂方法模式、抽象工厂模式
一、简单工厂模式(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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端