设计模式你怎么看?--简单工厂模式
一 前言
设计模式你怎么看? 我会写一个系列,因为自己最近才开始了解设计模式,说来惭愧毕业快两年了才开始学习,之所以迫切的觉得自己需要学习设计模式,是因为在工作中发现总感觉自己的代码不完美,但又想不出什么办法去改善,又感觉代码基本上都是面向过程的,而非面向对象。对于面向对象的概念也只是空喊概念 "继承,多态,封装" 而并没有真正融入到代码中去。
在没想学设计模式前,我总以为既然和设计有关那一定要有非富的编码经验和设计能力,才能理解和利用设计模式。 但!当我开始了了解设计模式时,我是万分后悔,自己的想法太天真了,自己还是 Too young Too simple,其实设计模式就应该在对于编程语言的语法熟悉 经历了一段时间的编程后 就应该开始了解,在此我真心的建议园子里还没有接触 设计模式的 朋友,不要再犹豫了立马行动起来,我可以肯定的说 了解设计模式后 对于 自己的思想高度会有一个质的提升。
以上是自己对于设计模式的一点感悟,可能很片面但只是我自己的一点想法。下面开始敲开设计模式的大门吧,这里面的东西,也许你看不明白,但是不要紧,随着时间的推移,总有一天你会恍然大悟的!!
二 介绍 设计模式
2.1 什么是设计模式 :设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样(摘自百度百科)
2.2 设计模式分类: 设计模式 分为原则与模式原则有如下几种 单一职责,开放-封闭原则,依赖倒转原则,迪米特法则,接口隔离原则,Liskov替换原则
而模式则有20多种 这里就不列举了,我会在后面的文章中逐一写出的。
三 第一个模式 简单工厂模式
3.1 什么是工厂模式
首先从文字上理解 工厂通常都是用于生产产品的,而对于产品的用户是不关心生产流程的,只关心最后生产出来的结果,而在代码中工厂类通常用于实例化具体的类并返回类的实例给调用者,使得调用者不用关心这个实例化的过程是怎样的,得到实例后只管用就好。
3.2 为什么要用工厂模式
设计模式最终的目的就是想 通过封装 继承 多态 把程序的耦合降低,增加程序的复用性,可维护性,减少重复代码等等,把面向过程的开发方式转为面向对象。
3.3 工厂模式UML类图
通过上面的UML图 大至可以了解工厂模式的结构,我们以鸟这一生物种类来举例,先定义了Bird基类 所有的鸟肯定都是有羽毛与翅膀的,
所以我们定义这两个方法Feather(羽毛) 与Wing(翅膀),然后让各种具体的鸟(Ostrich,Sparrow,Eagle)去继承Bird基类并选择性的重写基类方法,
因为并不是所有鸟类羽毛翅膀都是一至的。
然后通过Factory(工厂类)来创建客户端所需要的具体实例,下面来看代码是如何体现这一关系的
3.4 工厂模式代码
Bird 类 定义所有鸟类所共有的特性
/// <summary> /// 所有鸟类的抽象基类 /// </summary> public abstract class Bird { public virtual void Feather() { Console.Write("我有羽毛了\r\n"); } public virtual void Wing() { Console.Write("我有翅膀了\r\n"); } }
老鹰属性鸟类 具有鸟类特有属性 翅膀与羽毛,但是老鹰的翅膀比一般的鸟在宽阔所以可以重写Bird基类中的Wing方法体现自己的特性
class Eagle:Bird { public override void Feather() { base.Feather(); } public override void Wing() { Console.Write("我是老鹰我的翅膀很宽阔!\r\n"); } }
驼鸟 (Ostrich )与鹰(Eagle)一样属于鸟类,但驼鸟却不会飞所以也重写了Wing方法
public class Ostrich : Bird { public override void Feather() { base.Feather(); } public override void Wing() { Console.Write("我是驼鸟有翅膀也不能飞!\r\n"); } }
Sparrow同上
class Sparrow:Bird { public override void Feather() { Console.Write("我是麻雀我的羽毛是麻色的!\r\n"); } public override void Wing() { base.Wing(); } }
工厂类
结合我们的实际生活,工厂是用于生产 产品的,整个生产过程对于工厂内部是可见的,所以可以从代码中看到具体的实例化过程
public class Factory { public static Bird CreateInstance(string birdType) { Bird instance = null; switch (birdType) { case "Ostrich": instance =new Ostrich(); break; case "Eagle": instance = new Eagle(); break; case "Sparrow": instance = new Sparrow(); break; } return instance; } }
客户端调用类
客户端就好比是用户,当用户需要某一产品时,是不需要知道这个产品是如何生产出来的,只要得到我想要的产品就行。而生产的过程已被封装到工厂类(Factory)中
class Program { static void Main(string[] args) { Console.WriteLine("输入要生成鸟~~ Eagle Ostrich Sparrow"); string item = Console.ReadLine().Trim(); Bird instance = Factory.CreateInstance(item); instance.Feather(); instance.Wing(); Console.ReadLine(); } }
运行结果如下
一个简单的工厂模式的代码就写完了,但是以上代码还是有问题它违背了开放封闭原则(对新增是开的对修改是封闭的)什么意思呢?
如果某天需求变更,突然要加一种新的鸟比如"企鹅" 那我们的做法是 1 ,新增"企鹅类"并继承Bird类 2,在工厂类与客户端类中都加一条分支语句
来判断是否实例化该类,而这一操作就违背了开放封闭原则,至于如何解决这一问题,在后续的文章中会陆续回答。
四 总结
有几个月没写文章了,感觉还是没有彻底把自己把所想的表达出来,设计模式我也是最近才开始研究,对于它的理解肯定也是很浅显的,若要把设计模式灵活的应用到项目中去,必然是要经过大量的编程实践才能明白它的精髓,每一位大牛的成长,必然是有菜鸟这个阶段的,只要肯坚持努力,菜鸟逆袭也只是时间问题!
本人技术与文字水平实在有限,如有理解不对之处还望指出!
如果您觉得本文有给您带来一点收获,不妨点个推荐,为我的付出支持一下,谢谢~
如果希望在技术的道路上能有更多的朋友,那就关注下我吧,让我们一起在技术的路上奔跑