设计模式1:C#开发中使用创建型的工厂模式和行为型的策略模式

news2024/11/15 15:56:12

一、接口设计的好处

三大好处:解耦、可复用、可扩展。

二、简单工厂模式

【三要素】能创建具体产品的工厂、抽象产品(接口)、具体产品

【基本用法】字符串=>创建对象=>调用其方法

// 产品接口
public interface IProduct
{
    void Operation();
}

// 具体产品 A
public class ProductA : IProduct
{
    public void Operation() => Console.WriteLine("ProductA Operation");//表达式主体方法写法,就是写括号
}

// 具体产品 B
public class ProductB : IProduct
{
    public void Operation() => Console.WriteLine("ProductB Operation");
}

// 工厂类
public class ProductFactory
{
    public static IProduct CreateProduct(string type)
    {
        return type switch //简化版switch 语句,和if,else一个意思
        {
            "A" => new ProductA(),
            "B" => new ProductB(),
            _ => throw new ArgumentException("Invalid product type")
        };
    }
}

// 主程序
class Program
{
    static void Main()
    {
        string input = "A";
        IProduct product = ProductFactory.CreateProduct(input);
        product.Operation(); // Output: ProductA Operation
    }
}

【思考】以下方法也可以调用接口,为什么非要用工厂模式呢?

string input = "A";
if (input=="A")
{
    var product = new ProductA();
    product.Operation();
}

        请看图,我告诉你为什么要用工厂模式:

1.假如后续我加了产品CDEFGHI...,我仅需要添加代码到工厂类和具体实现 (底层代码),而无需修改高层代码,做到了开闭原则

2.用工厂模式实现了解耦,避免了高层代码和底层代码紧密的联系,使得高层代码无需关注具体的实现过程,做到了依赖于抽象,不依赖于具体(依赖倒置原则)。

三、抽象工厂模式

【思考】简单工厂和抽象工厂的区别

简单工厂模式:适用于单一类型的对象创建。
抽象工厂模式:适合创建一系列相关的产品族,每个产品族包含多个不同类型的产品。它提供了更高的灵活性和扩展性。

【代码实现】 

// 抽象产品 A
public interface IProductA
{
    void OperationA();
}

// 抽象产品 B
public interface IProductB
{
    void OperationB();
}

// 具体产品 A1
public class ProductA1 : IProductA
{
    public void OperationA() => Console.WriteLine("ProductA1 OperationA");
}

// 具体产品 B1
public class ProductB1 : IProductB
{
    public void OperationB() => Console.WriteLine("ProductB1 OperationB");
}

// 具体产品 A2
public class ProductA2 : IProductA
{
    public void OperationA() => Console.WriteLine("ProductA2 OperationA");
}

// 具体产品 B2
public class ProductB2 : IProductB
{
    public void OperationB() => Console.WriteLine("ProductB2 OperationB");
}

// 抽象工厂
public interface IFactory
{
    IProductA CreateProductA();
    IProductB CreateProductB();
}

// 具体工厂 1
public class Factory1 : IFactory
{
    public IProductA CreateProductA() => new ProductA1();
    public IProductB CreateProductB() => new ProductB1();
}

// 具体工厂 2
public class Factory2 : IFactory
{
    public IProductA CreateProductA() => new ProductA2();
    public IProductB CreateProductB() => new ProductB2();
}

// 主程序
class Program
{
    static void Main()
    {
        IFactory factory = new Factory1();
        IProductA productA = factory.CreateProductA();
        IProductB productB = factory.CreateProductB();
        
        productA.OperationA(); // Output: ProductA1 OperationA
        productB.OperationB(); // Output: ProductB1 OperationB
    }
}

四、策略模式

【三要素】环境类(用户这个对象)、策略接口、实现接口

【基本用法】对象不同=>选择的策略不同=>实现策略不同 

【demo】

using System;

public interface IDiscountStrategy
{
    double ApplyDiscount(double price);
}

public class GoldMemberDiscount : IDiscountStrategy
{
    public double ApplyDiscount(double price)
    {
        return price * 0.95; // 5% off
    }
}

public class RegularMemberDiscount : IDiscountStrategy
{
    public double ApplyDiscount(double price)
    {
        return price; // No discount
    }
}

public class Ticket
{
    private readonly IDiscountStrategy _discountStrategy;

    public Ticket(IDiscountStrategy discountStrategy)
    {
        _discountStrategy = discountStrategy;
    }

    public double GetPrice(double originalPrice)
    {
        return _discountStrategy.ApplyDiscount(originalPrice);
    }
}

public class Program
{
    public static void Main()
    {
        double originalPrice = 100.0;
        
        //策略模式:分为两步
        Ticket goldMemberTicket = new Ticket(new GoldMemberDiscount());//1.选择策略
        Console.WriteLine("Gold Member Price: " + goldMemberTicket.GetPrice(originalPrice));//2.执行策略

        Ticket regularMemberTicket = new Ticket(new RegularMemberDiscount());
        Console.WriteLine("Regular Member Price: " + regularMemberTicket.GetPrice(originalPrice));
    }
}

 【思考】为什么要选取策略模式?其实分析思路和工厂模式差不多:
1.符合开闭原则,新加策略可以直接加实现策略即可,而工厂模式还需要修改工厂类和实现产品。
2.消除if-else语句,将算法逻辑封装在了具体策略中,高层代码(主程序)只需要调用GetPrice 方法即可(用户的身份信息可由查表获得,无需if判断)。
3.复用性强,一套算法可以多次使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2108183.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计组易混淆概念梳理助记】机器字长、指令字长、存储字长、数据通路宽度...各种字长大杂炖,应该如何区分?谁又应该等于谁?

苏泽 “弃工从研”的路上很孤独,于是我记下了些许笔记相伴,希望能够帮助到大家 所有学过计组的人几乎都有一个烦恼 就是里面的概念无法记住 经典“转头忘” 那究竟是为什么?很显然 因为名词之间没形成结构化 点与点之间无法建立联系 在…

学AI绘画必知!文生图与图生图的基本认知

​ 在AI绘画的学习与使用中,无论是入门小白还是进阶高手,都绕不开两个核心概念:文生图和图生图。 这是所有AI绘画工具的根本操作方法。掌握这两者的基本原理,你便能轻松驾驭大多数AI工具,无论是MidJourney、Stable Dif…

创建makefile来运行其他目录下的makefile

上述makefile运行后,会报错产生结果: 需要一个伪目标all。

街机 SNK NeoGeo 中英文名字与驱动对照表

Part.I 简介 本文列举了街机 NeoGeo 中游戏的中英文名字与其驱动的对照,以帮助诸位更快地找到自己想玩的游戏。 注意:汉化版的街机模拟器 Kawaks 中游戏的中文名字是根据英文直译的,并不是习惯性的中文叫法。比如『三国志』英文名为『Warrio…

【案例67】Npart批量启动服务卡顿严重分析过程

问题现象 通过Npart启动NC服务,发现只启动一个,大概3min左右即可启动成功。但是批量启动服务需要几十分钟才可以把服务启动成功,启动卡在获取“wenjian”图标处。 绕过Npart直接写脚本并行启动相关服务,发现也需要30min 问题分析…

嵌入式OpenHarmony系统的一些特点

大家好,今天主要给大家分享一下,如何使用OpenHarmony,它的一些基本特点。 第一:为5G通讯做准备 OpenHarmony诞生与5G时代,5G不仅可以实现人与人,以及人与物,物与物之间的高速通讯,软件处理速度更快,可以操作的硬件也更多,可以说OpenHarmony是新一代万物互联的操作系…

【2024数模国赛赛题思路公开】国赛D题第二套思路丨附可运行代码丨无偿自提

2024年国赛D题解题第二套思路 【问题分析】 D题为投弹命中概率分析问题,有三种情况可以实现成功命中,并且可以发现这三种情况是互不重叠的,故实际投弹命中率可以表示为三种情况概率的累加,通过最后分析概率函数对投弹落点平面坐…

微信小程序rpx和px关系

微信小程序中使用了自定义的尺寸单位 rpx(responsive pixel),这是一种相对单位,用于适配不同屏幕尺寸的设备。rpx 的设计目的是为了让开发者能够更容易地写出跨屏幕尺寸的应用,而不需要为每个屏幕尺寸单独写一套样式。…

为什么这么多物联网项目都失败了?

甚至超过 50% 的智慧布署,在概念阶段停滞不前,这让一些真正有前途的物联网项目都失败了。 这些严峻的数字可能令人费解,尤其是因为它们仍然没有阻止行业参与物联网技术,因为投资者越来越意识到,物联网提供了最激烈的竞…

Origin2024中如何添加误差带?直观查看数据的变化范围

误差线是通常用于统计或科学绘图中,本期给大家分享Origin中绘制带填充区的误差带图,可以直观显示数据的变化范围,填充区域也可以增加视觉效果和美观性 操作步骤: 1、打开Origin2024软件,然后在Book1中输入如下示例数…

[PS]Photoshop 2024下载安装教程附软件包百度网盘分享链接地址

Photoshop 2024下载安装教程: Photoshop是一款修图软件,可以是目前位置最全的修图软件。是图片设计师必备的技能。 如何安装PS? 可以通过网盘链接获取:https://pan.baidu.com/s/1er557ksNcOOqj7zfpi5Lhg?pwdrzo0 提取码:rzo0…

Vue3.0项目实战(三)——大事件管理系统首页 layout 架子与文章分类的实现

目录 1. 首页 layout 架子 [element-plus 菜单] 1.1 基本架子拆解 2. 登录访问拦截 2.1 需求 2.2 vue3 和 vue2 中的 Vue-Router 区别 3. 用户基本信息获取&渲染 4. 退出功能 [element-plus 确认框] 5. 文章分类页面 - [element-plus 表格] 5.1 基本架子 - PageCo…

《佛脚闪卡watch》——Apple Watch上的高效学习助手

在快节奏的生活环境中,时间管理成为了学习成功的关键因素之一。**《佛脚闪卡watch》**是一款专为Apple Watch设计的应用程序,旨在帮助学生和自学者更高效地利用碎片时间进行学习。无论是等待公交、散步还是短暂休息,您都可以随时随地进行复习…

除谷歌翻译外,好用的翻译工具推荐!

翻译工具的存在方便了我们阅读跨语种的文件,跨文化交流变得前所未有的便捷。今天,就让我们一起来探索包括谷歌翻译的几款深受用户喜爱的翻译工具吧! 福昕在线翻译 直达链接: https://fanyi.pdf365.cn/ 福昕在线翻译是一款专注…

一、VSCode安装IDF5.3

目录 一、VSCode安装1、下载/安装 VSCode2、VSCode 的设置 二、VSCode安装IDF插件1、安装 IDF2、切换 IDF 版本3、从本地创建例程4、从服务器创建例程 一、VSCode安装 1、下载/安装 VSCode 下载地址:https://code.visualstudio.com/ 点击下载按钮。 下载安装 根据…

【 EI国际推荐会议 | 早鸟优惠 | 征稿启事】2025年计算机视觉、模式识别与检测国际会议(ICVPRD 2025)

Advanced Algorithms | Image Processing Technologies Oct. 25 - 26, 2025 ChongqingChina | 重庆中国 2025年计算机视觉、模式识别与检测国际会议(ICVPRD 2025) 会议官网:https://www.ic-vprd.org/ 会议时间:2025年10月25-2…

从0开始深度学习(5)——线性回归的逐步实现

将从零开始实现整个方法, 包括数据流水线、模型、损失函数和小批量随机梯度下降优化器,但现代的深度学习框架几乎可以自动化地进行所有这些工作,但从零开始实现可以确保我们真正知道自己在做什么。 下一章会使用框架简洁的实现线性回归 # 提前…

孩子成长的黄金期,做好这件事,给孩子培养一个“超级大脑“!

唤醒我们的大脑能力,开发大脑的无限功能,可以提高自己的学习和工作效率,帮我们实现更好的生活状态。 而孩子在6-12岁这个阶段,正是具体想象思维向抽象思维过渡的关键时期,所以这个阶段正是训练孩子逻辑思维能力的好时…

如何在本地服务器部署SeaFile自托管文件共享服务结合内网穿透打造私有云盘?

文章目录 1. 前言2. SeaFile云盘设置2.1 Owncould的安装环境设置2.2 SeaFile下载安装2.3 SeaFile的配置 3. cpolar内网穿透3.1 下载安装3.2 Cpolar注册3.3 Cpolar云端设置3.4 Cpolar本地设置 4.公网访问测试5.结语 1. 前言 本文主要为大家介绍,如何使用两个简单软件…

钢铁百科:Q420DR力学性能、Q420DR执行标准、Q420DR低温容器钢板

Q420DR钢板是一种专为低温压力容器设计的优质钢材,其材质特性、执行标准、化学成分、力学性能、交货状态、应用范围以及常用规格等方面都具有显著的特点。 一、Q420DR钢板材质 Q420DR钢板的命名方式体现了其材质特性。其中,“Q”代表屈服强度&#xff…