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
猜你喜欢
- 概述Spring Cloud中,客户端的负载均衡使用的是Ribbon,Ribbon的超时时间默认很短,需要进行调整。Spring Cloud
- 在Spring4之后,要使用注解开发,必须要保证aop的包导入了使用注解需要导入context约束,增加注解的支持!<?xml ver
- Java排序 - DualPivotQuicksort这里描述 leftmost = true 的情况,也就是会从数组的开始一直排序到数组的
- java生成json隐藏关键属性今天在工作中遇到一个这样的问题,当后端返回数据时一些关键信息或敏感信息并不想返回到前端,但是又懒得定义专用的
- 前言在最近的一个项目需要用JAVA来解析DICOM图片,DICOM被广泛应用于放射医疗,心血管成像以及放射诊疗诊断设备(X射线,CT,核磁共
- 封面图下个季度的目标是把前端监控相关的内容梳理出来,梳理出来之后可能会在公司内部做个分享~Flutter应用程序既括代码也包括一些其他的资产
- 前言本文主要给大家介绍了关于java poi导入Excel通用工具类的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍
- 一、下载安装包 1. JDK1.8百度云下载路径:百度网盘下载链接: https://pan.baidu
- C#调用C++ dll string类型返回为了这个问题,百度了一堆不靠谱的资料,什么C#调用c++类型对应啥的,说用string ,Str
- 本章将具体讲解下拉菜单的交互。使用下拉菜单(Dropdown)插件,您可以向任何组件(比如导航栏、标签页、胶囊式导航菜单、按钮等)添加下拉菜
- 1.项目简绍本项目使用SpringBoot开发,jdbc5.1.48 Mybatis 源码可下载其中涉及功能有:Mybatis的使用,Thy
- 本文实例讲述了JFreeChart插件实现的折线图效果。分享给大家供大家参考,具体如下:package com.lei.jfreechart
- 本教程将介绍如何在 Spring Boot 应用程序中使用 Kafka。Kafka 是一个分布式的发布-订阅消息系统,它可以处理大量数据并提
- C# 关于Invoke首先说下,invoke和begininvoke的使用有两种情况:control中的invoke、begininvoke
- 本文实例为大家分享了java实现单链表、双向链表的相关代码,供大家参考,具体内容如下java实现单链表:package code;class
- 摘要本文主要介绍基于SpringBoot定时任务ScheduledTaskRegistrar的动态扩展,实现定时任务的动态新增和删除。Sch
- 目录前言1、饿汉式(线程安全)⭐2、懒汉式(线程不安全)⭐3、懒汉式(加锁)4、懒汉式(双重校验锁)⭐5、单例模式(静态内部类)6、单例模式
- 返回集合为null还是空集合及空集合的三种写法个人认为在自己写接口时,需要返回集合时返回一个空集合,比如mybatis查询如果返回一个集合,
- Java动态数组Arraylist存放自定义数据类型class Point{ int x; int y; public Point(int
- 一、首先我们先大致了解一下什么是多线程。(书上的解释)程序是一段静态的代码,它是应用软件的蓝本。进程是程序的一次动态执行过程,对