百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

C#设计模式之0-简单工厂模式(c# 工厂模式加泛型)

liebian365 2024-11-17 13:17 23 浏览 0 评论

简单工厂模式(Simple Factory Pattern)

简单工厂模式属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GoF设计模式之一。学习简单工厂模式是学习其它工厂模式的前提条件。

简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

角色

1、工厂(Creator)

简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象;

2、抽象产品(Product)

简单工厂模式所创建的所有对象的抽象基类,它负责描述所有实例所共有的公共接口;

3、具体产品(Concrete Product)

这是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。

示例

命名空间SimpleFactory中包含抽象水果基类Fruit、三个具体水果类、水果工厂类FruitFactory、未知水果异常类UnknowFruitException。本案例将向大家展示如何使用简单工厂模式来生产不同种类的水果。

namespace SimpleFactory
public abstract class Fruit {
 
    protected Color Color { get; set; } = Color.Orange;
 
    protected abstract string BornInfo();
 
    protected const string LINE_BREAK =
        "------------------------------------------------------------";
 
    public void WhatsFruit() {
        Console.WriteLine("Printing!");
        OnPrint();
        Console.WriteLine("Printed!");
        OnPrinted();
    }
 
    protected virtual void OnPrint() {
        Console.WriteLine(#34;I'm a(n) {this.ToString().Replace(nameof(SimpleFactory) + ".", "")} " +
                            #34;with {Color.ToString()} and I born in {BornInfo()}!");
    }
 
    protected virtual void OnPrinted() {
        Console.WriteLine(LINE_BREAK);
    }
 
}

抽象水果基类Fruit 包含颜色Color属性、出生信息BornInfo抽象方法、这是什么水果WhatsFruit方法、打印水果OnPrint和打印完OnPrinted方法。

C#开发笔记之01-为什么开源框架会大量的使用protected virtual?

public class Apple : Fruit {

    public Apple() {
        Color = Color.Red;
    }

    protected override string BornInfo() => "summer";

    protected override void OnPrint() {
        Console.WriteLine(#34;I'm an apple with {Color.ToString()},not an IPhone!");
    } 

}
public class Orange : Fruit {

    protected override string BornInfo() => "autumn";

    protected override void OnPrinted() {
        Console.WriteLine("override OnPrinted()!");
        Console.WriteLine(LINE_BREAK);
    }

}
public class Pear : Fruit {

    public Pear() {
        Color = Color.Yellow;
    }

    protected override string BornInfo() => "China";

}

具体水果类,苹果Apple类、橘子Orange类和梨子Pear类,各自实现或重写不同的构造函数、抽象方法、虚拟方法和属性。

public enum FruitType {
    Unknow = -1,
    Apple,
    Orange,
    Pear
}
public static class FruitFactory {

    public static Fruit CreateFruit(FruitType type) {
        Fruit fruit = null;
        switch (type) {
            case FruitType.Apple:
                fruit = new Apple();
                break;
            case FruitType.Orange:
                fruit = new Orange();
                break;
            case FruitType.Pear:
                fruit = new Pear();
                break;
            default:
                throw new UnknowFruitException();
        }

        return fruit;
    }

}

水果工厂类FruitFactory,该类是简单工厂的核心类,包含CreateFruit方法,传递FruitType参数以便确定产出何种水果。方法返回抽象水果基类,以便调用方使用基类变量接受返回值。

public class UnknowFruitException : Exception {

    public UnknowFruitException()
        : base("Not Supported Fruit!") {

    }

    public UnknowFruitException(string message, Exception innerException)
        : base(message, innerException) {

    }

}

使用未知水果异常类UnknowFruitException,进行简单的异常处理。

public static void Main(string[] args) {
    try {
        var fruit = FruitFactory.CreateFruit(FruitType.Pear);
        fruit.WhatsFruit();

        fruit = FruitFactory.CreateFruit(FruitType.Apple);
        fruit.WhatsFruit();

        fruit = FruitFactory.CreateFruit(FruitType.Orange);
        fruit.WhatsFruit();

        fruit = FruitFactory.CreateFruit(FruitType.Unknow);
        fruit.WhatsFruit();
    }
    catch (UnknowFruitException ex) {
        Console.WriteLine(nameof(UnknowFruitException) + ":" + ex.Message);
    }
    catch (Exception ex) {
        Console.WriteLine(nameof(Exception) + ":" + ex.Message);
    }

    Console.ReadKey();
}

调用方用变量fruit接受水果工厂不同的产出,由WhatsFruit方法在控制台打印出水果信息,用catch分别处理不同类型的异常。以下是这个案例的输出结果:

Printing!
I'm a(n) Pear with Color [Yellow] and I born in China!
Printed!
-----------------------------------------------------------
Printing!
I'm an apple with Color [Red],not an IPhone!
Printed!
-----------------------------------------------------------
Printing!
I'm a(n) Orange with Color [Orange] and I born in autumn!
Printed!
override OnPrinted()!
-----------------------------------------------------------
UnknowFruitException:Not Supported Fruit!

优点

1、工厂类是整个模式最核心的部分,包含了对象的创建逻辑。调用者无需关心对象创建的细节,只要给出参数,就可以得到相应的对象;2、他们之间相互独立,各司其职,有利于整个软件体系架构。

缺点

1、由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则;2、将全部创建逻辑集中到了一个工厂类中,如果需要添加新的类,则就需要改变工厂类了,明显违反开闭原则。工厂方法模式中这个问题有一定程度的缓解。

使用场景

1、工厂类负责创建的对象比较少;2、客户只知道传入工厂类的参数,对于创建对象的细节不关心或无法知道;3、由于简单工厂很容易违反高内聚责任分配原则,所以在实际开发中很少用到。

相关推荐

go语言也可以做gui,go-fltk让你做出c++级别的桌面应用

大家都知道go语言生态并没有什么好的gui开发框架,“能用”的一个手就能数的清,好用的就更是少之又少。今天为大家推荐一个go的gui库go-fltk。它是通过cgo调用了c++的fltk库,性能非常高...

旧电脑的首选系统:TinyCore!体积小+精简+速度极快,你敢安装吗

这几天老毛桃整理了几个微型Linux发行版,准备分享给大家。要知道可供我们日常使用的Linux发行版有很多,但其中的一些发行版经常会被大家忽视。其实这些微型Linux发行版是一种非常强大的创新:在一台...

codeblocks和VS2019下的fltk使用中文

在fltk中用中文有点问题。英文是这样。中文就成这个样子了。我查了查资料,说用UTF-8编码就行了。edit->Fileencoding->UTF-8然后保存文件。看下下边的编码指示确...

FLTK(Fast Light Toolkit)一个轻量级的跨平台Python GUI库

FLTK(FastLightToolkit)是一个轻量级的跨平台GUI库,特别适用于开发需要快速、高效且简单界面的应用程序。本文将介绍Python中的FLTK库,包括其特性、应用场景以及如何通过代...

中科院开源 RISC-V 处理器“香山”流片,已成功运行 Linux

IT之家1月29日消息,去年6月份,中科院大学教授、中科院计算所研究员包云岗,发布了开源高性能RISC-V处理器核心——香山。近日,包云岗在社交平台晒出图片,香山芯片已流片,回片后...

Linux 5.13内核有望合并对苹果M1处理器支持的初步代码

预计Linux5.13将初步支持苹果SiliconM1处理器,不过完整的支持工作可能还需要几年时间才能完全完成。虽然Linux已经可以在苹果SiliconM1上运行,但这需要通过一系列的补丁才能...

Ubuntu系统下COM口测试教程(ubuntu port)

1、在待测试的板上下载minicom,下载minicom有两种方法:方法一:在Ubuntu软件中心里面搜索下载方法二:按“Ctrl+Alt+T”打开终端,打开终端后输入“sudosu”回车;在下...

湖北嵌入式软件工程师培训怎么选,让自己脱颖而出

很多年轻人毕业即失业、面试总是不如意、薪酬不满意、在家躺平。“就业难”该如何应对,参加培训是否能改变自己的职业走向,在湖北,有哪些嵌入式软件工程师培训怎么选值得推荐?粤嵌科技在嵌入式培训领域有十几年经...

新阁上位机开发---10年工程师的Modbus总结

前言我算了一下,今年是我跟Modbus相识的第10年,从最开始的简单应用到协议了解,从协议开发到协议讲解,这个陪伴了10年的协议,它一直没变,变的只是我对它的理解和认识。我一直认为Modbus协议的存...

创建你的第一个可运行的嵌入式Linux系统-5

@ZHangZMo在MicrochipBuildroot中配置QT5选择Graphic配置文件增加QT5的配置修改根文件系统支持QT5修改output/target/etc/profile配置文件...

如何在Linux下给zigbee CC2530实现上位机

0、前言网友提问如下:粉丝提问项目框架汇总下这个网友的问题,其实就是实现一个网关程序,内容分为几块:下位机,通过串口与上位机相连;下位机要能够接收上位机下发的命令,并解析这些命令;下位机能够根据这些命...

Python实现串口助手 - 03串口功能实现

 串口调试助手是最核心的当然是串口数据收发与显示的功能,pzh-py-com借助的是pySerial库实现串口收发功能,今天痞子衡为大家介绍pySerial是如何在pzh-py-com发挥功能的。一、...

为什么选择UART(串口)作为调试接口,而不是I2C、SPI等其他接口

UART(通用异步收发传输器)通常被选作调试接口有以下几个原因:简单性:协议简单:UART的协议非常简单,只需设置波特率、数据位、停止位和校验位就可以进行通信。相比之下,I2C和SPI需要处理更多的通...

同一个类,不同代码,Qt 串口类QSerialPort 与各种外设通讯处理

串口通讯在各种外设通讯中是常见接口,因为各种嵌入式CPU中串口标配,工业控制中如果不够还通过各种串口芯片进行扩展。比如spi接口的W25Q128FV.对于软件而言,因为驱动接口固定,软件也相对好写,因...

嵌入式linux为什么可以通过PC上的串口去执行命令?

1、uboot(负责初始化基本硬bai件,如串口,网卡,usb口等,然du后引导系统zhi运行)2、linux系统(真正的操作系统)3、你的应用程序(基于操作系统的软件应用)当你开发板上电时,u...

取消回复欢迎 发表评论: