当前位置: 首页 > 科技观察

值得永久珍藏的C#设计模式例程

时间:2023-03-13 11:44:03 科技观察

网上关于设计模式的说法一大堆,我们就不说了。在我的理解中,设计模式是很多NB大佬针对特定情况总结出来的标准方案。既然是标准方案,就要有套路,要有标准的样子。几种常见的设计模式都有自己的例程模板。下面进入正题,我们来一一说。1.抽象工厂模式抽象工厂的主要场景是创建一系列相关或相似的对象。请注意,这是相关或相似的。由于这个特点,我们可以抽取共同点,形成接口或抽象类,然后通过这个接口或抽象类派生出各种对象。为什么叫抽象工厂呢?我不知道,也没关系。在我看来,只是一个名字,记下来就好了。东西出来了,总得有个名字吧。有人出来说,我们就叫抽象工厂吧。所以它被称为抽象工厂。就像一个人建立了一个网站,然后让别人在上面卖东西。后来做大了,需要推广,就需要给这种经营方式起个名字,于是就出现了B2C。现在人做电商,首先要讨论的是做B2B还是B2C。恰恰相反。先做起来,赚钱才是最重要的。当它变大时,无论你怎么称呼它,人们都会倾听并相信你。让我们离题,:P?先写几个类型,包括接口和实体类,后面会用到://接口定义publicinterfaceILaptop{voidGetInfo();}publicinterfaceIMobile{voidGetInfo();}//实体类一publicclassMateBook:ILaptop{publicvoidGetInfo(){Console.WriteLine("IamMateBook");}}publicclassMac:ILaptop{publicvoidGetInfo(){Console.WriteLine("IamMac");}}//实体类二publicclassMate:IMobile{publicvoidGetInfo(){Console.WriteLine("IamMate");}}publicclassIPhone:IMobile{publicvoidGetInfo(){Console.WriteLine("IamIPhone");}}有了上面的类型,我们再来看看抽象工厂的套路。定义:publicinterfaceIFactory{ILaptopCreateLaptop();IMobileCreateMobile();}publicclassFactoryA:IFactory{publicILaptopCreateLaptop(){returnnewMateBook();}publicIMobileCreateMobile(){returnnewMate();}}publicclassFactoryB:IFactory{publicILaptopCreateLaptop(){Mobilereturn}n(){returnnewIPhone();}}调用:publicstaticclassExample{publicstaticvoidExampleTest(){varfactoryA=newFactoryA();varlaptopA=factoryA.CreateLaptop();varmobileA=factoryA.CreateMobile();laptopA.GetName();mobileA.GetName();varfactoryB=newFactoryB();varlaptopB=factoryB.CreateLaptop();varmobileB=factoryB.CreateMobile();laptopB.GetName();mobileB.GetName();}//result://IamMateBook//IamMate//IamMac//IamiPhone}在这种模式下,核心部分是工厂接口的定义:publicinterfaceIFactory{ILaptopCreateLaptop();IMobileCreateMobile();}在这个工厂接口中,增加了多个类似的接口。因此,调用者可以很方便地用类似的方式调用,并且在工厂实体中,区分内部引用的实体。一个典型的场景是:一个程序面对多种数据库。这样的话,可以区分工厂实体中连接的是哪个数据库,内部引用实体对应不同的数据库。对外调用时,只需要在初始化时确认使用哪个数据库,然后直接用于后续的增删改查操作,调用方不需要考虑数据库之间的差异。其实这也是抽象工厂使用最多的场景。第二,工厂模型去掉了abstract这个词,它仍然是一个模型,而且是不同的模型。这个名字已经够混乱了。不过说实话,工厂模式和抽象工厂模式很像,不同的是:抽象工厂模式是在工厂模式的基础上,又做了一层抽象。看例程:publicinterfaceIFactory{ILaptopCreateLaptop();}publicclassFactoryA:IFactory{publicILaptopCreateLaptop(){returnnewMateBook();}}publicclassFactoryB:IFactory{publicILaptopCreateLaptop(){returnnewMac();}}publicstaticclassExample{publicstaticvoidactoryA()()varlaptopA=factoryA.CreateLaptop();laptopA.GetName();varfactoryB=newFactoryA();varlaptopB=factoryB.CreateLaptop();laptopB.GetName();}//result://IamMateBook//IamMac}看到了吧,确实很类似于抽象工厂。但是在使用中,工厂模式用的会比较多。任何类都可以写成工厂模式。这种模式最大的作用是对定义和实体进行分层。在开发过程中,有些人可以定义接口,有些人可以实现接口。此外,工作模式可以随时扩展为抽象工厂。比如一开始可能有很多种数据库,但是还没有确定具体的数据库,那么可以先按照工厂模型来写,等数据库定型了,就可以很方便的转成抽象工厂随时。3.建造者模式的名字就更看不懂了,就因为一个建造者?事实上,他说的是这样的事情。我们经常看到这样的代码:varmobile=newMobileBuilder().WithBrand("Apple").WithModel("13Pro").WithMemory("512G").Build();是不是看起来很洋气?看看这个Routine://这是一个数据模型publicclassMobile{publicstringBrand{get;set;}publicstringModel{get;set;}publicstringMemory{get;set;}}//这是Builder的定义publicclassMobileBuilder{privatereadonlyMobile_mobile=newMobile();publicMobileBuilderWithBrand(stringbrand){_mobile.Brand=brand;returnthis;}publicMobileBuilderWithModel(stringmodel){_mobile.Model=model;returnthis;}publicMobileBuilderWithMemory(stringmemory){_mobile.Memory=memory;returnthis;}publicMobileBuild(){return_mobile;}}然后你可以这样称呼它:.WriteLine(mobile.ToJson());}//result://{"Brand":"Apple","Model":"13Pro","Memory":"512G"}}个人很喜欢这个套路很多,没别的,就是洋气,很洋气的应用场景有很多。所有数据的DTO都可以写入。4.原型模式这个模式听起来可能有点奇怪。看了一些文章,也归类为一种创作模式。事实上,我更倾向于将其视为一种代码结构而不是一种模式。这种结构最大的用途就是复制——通过复制一个现有的实例来创建一个新的实例。代码是这样的:publicclassMobilePackage{publicstringColor{get;set;}publicMobileMobile{get;set;}//下面是模式代码publicMobilePackageShallowCopy(){return(MobilePackage)this.MemberwiseClone();}publicMobilePackageDeepCopy(){varclone=(MobilePackage)this.MemberwiseClone();clone.Color=newstring(Color);clone.Mobile=newMobile{Brand=newstring(Mobile.Brand),Model=newstring(Mobile.Model),Memory=newstring(Mobile.Memory),};returnclone;}}你看,其实就是一个拷贝代码。但是要注意,对于深拷贝和浅拷贝,涉及到指针和引用。不熟悉的,了解后再使用。看一下上面的结果:publicstaticclassExample{publicstaticvoidTest(){varmobilePackage=newMobilePackage{Color="White",Mobile=newMobile{Brand="Apple",Model="13Pro",Memory="512G",}};varshallowCopied=mobilePackage.ShallowCopy();vardeepCopied=mobilePackage.DeepCopy();mobilePackage.Color="Black";mobilePackage.Mobile.Brand="Huawei";mobilePackage.Mobile.Model="Mate";Console.WriteLine(mobilePackage.ToJson());Console.WriteLine(shallowCopied.ToJson());Console.WriteLine(deepCopied.ToJson());}//result://{"Color":"Black","Mobile":{"Brand":"Huawei","Model":"Mate","Memory":"512G"}}//{"Color":"White","Mobile":{"Brand":"Huawei","Model":"Mate","内存":"512G"}}//{"颜色":"白色","手机":{"品牌":"Apple","Model":"13Pro","Memory":"512G"}}}结果和你理解的一样吗?如果没有,研究一下value和reference的区别另外,C#10新出的Record是原型模式的典型类型,大家也可以了解一下。5、单例模式单例模式也是一种非常好用的模式,名字也比较直白。单例模式,简单来说就是无论你new多少次,实际应用的全局内存中都只有一个实例。套路代码非常简单:();}}}return_instance;}}这里有两点需要注意:类声明使用sealed关键字,保证这个类不会被派生。类构造器使用private来保证类不会是new的。这与单例本身无关,它只是一种表明这是单例的方式。控制单例的核心代码其实就是下面的GetInstance()方法。调用的时候是下面一行代码:Singletonsingleton=Singleton.GetInstance();没关系。设计模式有很多,对应的套路也有很多。其中,有的是简单无脑的套路,像上面的单例,有的则比较复杂。不过,既然是套路,总有固定的代码或结构可循。我打算写几篇关于这个主题的文章。这是第一个。最后一个小提示:虽然套路简单,但是在使用之前一定要看透。此外,有时简单的代码也能很好地完成工作,因此请确保不要过度使用。