C#设计模式之工厂模式
作者:.NET开发菜鸟 发布时间:2023-07-10 13:43:33
这是我们用得比较多的一种设计模式,也是23种标准设计模式之一,使用前面讲的简单工厂设计模式,遇到具体产品经常变换时就不太适合了,违反了开闭设计原则;怎么才能避免修改工厂类呢?工厂方法模式可以做到。
工厂方法模式要求我们应该有一个抽象的工厂类,我们知道尽量使用抽象类或接口来定义就可以达到一个开闭原则的效果,这样我们在抽象的工厂类定义一个生产产品的方法,这个方法就是工厂方法,这也是工厂方法模式的由来,他具体的行为会有他的子类或实现类来实现。如果想生产某种产品,就定义一个新的产品,新的产品工厂类,这样就实现了不同的产品进行一个不同的创建,这样如果有信的产品,只需要添加新的工厂类,原来写好的代码不会发生变化,这种方式符合开闭原则,可扩展比较好。
添加一个具体产品,只需要在添加一个具体产品的工厂类实现抽象工厂类,不需要修改原来的代码
示例代码:
抽象产品类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/*
动物抽象类
* 抽象产品
*/
public abstract class Animal
{
public abstract void Eat();
}
}
抽象工厂类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/*
动物抽象工厂类
*/
public abstract class AnimalFactory
{
public abstract Animal GetAnimal();
}
}
生产狗的具体工厂类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/// <summary>
/// 具体工厂:生成狗
/// </summary>
public class DogFactory :AnimalFactory
{
public override Animal GetAnimal()
{
return new Dog();
}
}
}
生产企鹅的具体工厂类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/// <summary>
/// 具体工厂:生成企鹅
/// </summary>
public class PenguinFactory :AnimalFactory
{
public override Animal GetAnimal()
{
return new Penguin();
}
}
}
具体产品狗类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/*
具体的产品类,实现抽象产品类
*/
public class Dog:Animal
{
// 实现抽象方法
public override void Eat()
{
Console.WriteLine("狗在吃饭!");
}
}
}
具体产品企鹅类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/*
具体产品类,实现抽象产品类
*/
public class Penguin : Animal
{
// 实现抽象方法
public override void Eat()
{
Console.WriteLine("企鹅在吃饭!");
}
}
}
客户端调用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
class Program
{
static void Main(string[] args)
{
AnimalEat(new DogFactory());
Console.ReadKey();
}
static void AnimalEat(AnimalFactory af)
{
Animal am = af.GetAnimal();
am.Eat();
}
}
}
类图:
如果想在增加一个Cat类,只需要增加一个具体的Cat类实现Animal类的方法,增加一个具体的Cat工厂类实现抽象工厂类即可,不需要在修改已经写好的代码,符合开闭原则。
使用接口的方式实现工厂模式
需求:使用面向对象的方式设计一个系统,描述使用卡车从事货运,使用公共汽车从事客运。使用工厂模式实现。
1、汽车接口:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/// <summary>
/// 汽车接口
/// </summary>
public interface ICar
{
/// <summary>
/// 描述汽车从事的活动
/// </summary>
void Work();
}
}
2、分别定义卡车(Truck)和公共汽车(Bus)类实现汽车接口(ICar)里面的Work()方法
Truck类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/// <summary>
/// 卡车类
/// </summary>
public class Truck : ICar
{
/// <summary>
/// 卡车从事的活动
/// </summary>
public void Work()
{
Console.WriteLine("卡车从事货运");
}
}
}
Bus类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/// <summary>
/// 公共汽车类
/// </summary>
public class Bus:ICar
{
/// <summary>
/// 公共汽车从事的活动
/// </summary>
public void Work()
{
Console.WriteLine("公共汽车从事客运");
}
}
}
3、定义汽车的工厂接口(ICarFactory):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/// <summary>
/// 汽车工厂接口
/// </summary>
public interface ICarFactory
{
ICar GetCar();
}
}
4、分别定义卡车工厂(TruckFactory)和公共汽车工厂(BusFactory)实现ICarFactory接口
TruckFactory工厂:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/// <summary>
/// 卡车工厂接口
/// </summary>
public class TruckFactory:ICarFactory
{
/// <summary>
/// 返回卡车类
/// </summary>
/// <returns></returns>
public ICar GetCar()
{
return new Truck();
}
}
}
BusFactory工厂:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
/// <summary>
/// 公共汽车工厂
/// </summary>
public class BusFactory:ICarFactory
{
/// <summary>
/// 返回公共汽车类
/// </summary>
/// <returns></returns>
public ICar GetCar()
{
return new Bus();
}
}
}
5、主程序调用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
class Program
{
static void Main(string[] args)
{
CarWork(new TruckFactory());
Console.ReadKey();
}
/// <summary>
/// 根据汽车工厂返回具体的汽车类
/// </summary>
/// <param name="cf"></param>
static void CarWork(ICarFactory cf)
{
ICar c = cf.GetCar();
c.Work();
}
}
}
6、程序运行结果
代码下载地址:点击下载
来源:https://www.cnblogs.com/dotnet261010/p/7352541.html


猜你喜欢
- 一、基本介绍 1、介绍学习很多算法知识,力争做到最优解的学习过程中,很多时候都会遇到PriorityQueue(优先队列)。一个基
- 1 修改项目打包类型在pom.xml里,项目打包类型将jar设置成war:<packaging>war</packagin
- 本文实例讲述了C#求n个数中最大值和最小值的方法。分享给大家供大家参考。具体实现方法如下:using System; using Syste
- 这篇文章主要介绍了配置springboot项目使用外部tomcat过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作
- 本文实例讲述了java swing实现的扫雷游戏及改进版。分享给大家供大家参考,具体如下:版本1:package awtDemo;impor
- 说明本实例能够监控聚划算的抢购按钮,在聚划算整点聚的时间到达时自动弹开页面(URL自己定义)。可以自定义监控持续分钟数,同时还可以通过多线程
- 前言前几天恰好面试一个应届生,问了一个很简单的问题:你了解过Mybatis中有几种传参方式吗?没想到其他问题回答的很好,唯独这个问题一知半解
- WCF实例(带步骤) <xmlnamespace prefix ="o" ns ="urn:schema
- 过滤掉其他的播放器,使用我自己的播放器来做 wv.set
- 实现功能:模拟简单登录功能,登录成功跳转新页面,登录失败在原登录界面提示登录失败信息开发环境:eclipseTomcat-8.0预备知识:H
- Android 实现记住用户名和密码的功能是通过SharedPreference 存储来实现的。创建一个复选按钮,通过按钮的否选取来进行事件
- 两种android图片裁剪方式,供大家参考,具体内容如下一、相机拍完照之后利用系统自带裁剪工具进行截取public static void
- 前言:仿微信通讯录搜索功能,通过汉字或拼音首字母找到匹配的联系人并显示匹配的位置一:先看效果图字母索引搜索匹配二:功能分析1:汉字转拼音通讯
- Java 中的运算符与 C 语言基本一致。1、算术运算符操作符描述例子+加法 : 相加运算符两侧的值A + B 等于 30-减法 : 左操作
- 前言前段时间看到了豆瓣FM的音乐播放界面,有一个环形的进度条,非常的好看,于是想了想,为什么不自己做一个呢,于是就开始了自定义的过程豆瓣FM
- using System; using System.Collections.Generic; using System.Linq; usi
- Java的接口和抽象类深入理解对于面向对象编程来说,抽象是它的一大特征之一。在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类。
- 本文基于GP58系列,它可以兼容ESC/POS指令集,对EPSON的打印机通用.Android下的设备调试,如果设备提供了驱动,按照厂家的驱
- 1、回顾一下大家有没有注意到,目前讲到的所有 controller 中的方法接收到请求之后,都是有返回值的,返回值主要有 2 种类型:1、
- 一、分析源码我们学完之前的框架,大概知道静态资源过滤是由mvc处理的,然后在分析自动装配的时候会遇到WebMvcAutoConfigurat