设计模式学习02:简单工厂模式、工厂模式以及抽象工厂模式(具体)
设计模式学习02:简单工厂模式、工厂模式以及抽象工厂模式(具体)
本文转载:https://www.cnblogs.com/toutou/p/4899388.html
作者:请叫我头头哥
- v写在前面
- v简单工厂模式
- v工厂方法模式
- v抽象工厂模式
- v博客总结
园子里关于23种设计模式的博文已经可以说是成千上万、车载斗量、屯街塞巷、不计其数、数不胜数、摩肩接踵、汗牛充栋、车水马龙、门庭若市、琳琅满目直至让人眼花缭乱了。在这样的大环境下之所以来写设计模式类的博文,并不是像一些"非主流"的爱情观那样"宁缺毋滥"。 只是其一呢,因为相当于给自己做一个总结,加深一下自己这方面的认识,因为掌握了和把它写出来我感觉后者还可以对技能有一个提升,其二呢是因为最近公司有一个内部的training需要讲设计模式。
1.介绍:
2.延伸:
3.模拟场景:
欧美主导的以赛车为主题的系列电影《速度与激情》系列相信大家都看过,里面的男主角(zhǔ jué,加个拼音,经常听到有人说什么主脚主脚的,虽然之前我也不确定是zhǔ jué还是主脚,但是我没念过主脚,我在不确定的情况下我都是念男一号)范·迪塞尔在每一集里面做不同的事情都是开不同的车子,相信大家都觉得很酷吧。
人家酷也没办法,谁叫人家是大佬呢。这里我们试想一下,如果这是一套程序,我们该怎么设计?每次不同的画面或者剧情范·迪塞尔都需要按照导演的安排开不一样的车,去参加赛车需要开的是跑车,可能导演就会说下一场戏:范·迪塞尔下一场戏需要开跑车(参数),要去参加五环首届跑车拉力赛,这时候场务(工厂类)接到导演的命令(跑车参数)后需要从车库开出一辆跑车(具体产品)交到范·迪塞尔手上让他去准备五环首届跑车拉力赛。这套程序的整个生命周期就算完成了。(什么?没完成?难不成你还真想来个五环首届跑车拉力赛了啊:)
根据导演不同的指令,开的车是不一样的,但是车都是在车库中存在的。车都属于同一种抽象,车库里所有的车都有自己的特征,这些特征就是条件。导演发出指令的时候,只要告诉场务特征,场务就知道提什么车。这就简单工厂模式的典型案例。
4.简单工厂UML类图: (UML图是我用windows自带的paint手工画的,所以可能不是很专业)
5.代码演示:
抽象产品类代码:
namespace CNBlogs.DesignPattern.Common {/// <summary>/// 抽象产品类: 汽车/// </summary>public interface ICar{void GetCar();} }
具体产品类代码:
namespace CNBlogs.DesignPattern.Common {public enum CarType{SportCarType = 0,JeepCarType = 1,HatchbackCarType = 2}/// <summary>/// 具体产品类: 跑车/// </summary>public class SportCar : ICar{public void GetCar(){Console.WriteLine("场务把跑车交给范·迪塞尔");}}/// <summary>/// 具体产品类: 越野车/// </summary>public class JeepCar : ICar{public void GetCar(){Console.WriteLine("场务把越野车交给范·迪塞尔");}}/// <summary>/// 具体产品类: 两箱车/// </summary>public class HatchbackCar : ICar{public void GetCar(){Console.WriteLine("场务把两箱车交给范·迪塞尔");}} }
简单工厂核心代码:
namespace CNBlogs.DesignPattern.Common {public class Factory{public ICar GetCar(CarType carType){switch (carType){case CarType.SportCarType:return new SportCar();case CarType.JeepCarType:return new JeepCar();case CarType.HatchbackCarType:return new HatchbackCar();default:throw new Exception("爱上一匹野马,可我的家里没有草原. 你走吧!");}}} }
客户端调用代码:
//------------------------------------------------------------------------------ // <copyright file="Program.cs" company="CNBlogs Corporation"> // Copyright (C) 2015-2016 All Rights Reserved // 原博文地址: http://www.cnblogs.com/toutou/ // 作 者: 请叫我头头哥 // </copyright> //------------------------------------------------------------------------------ namespace CNBlogs.DesignPattern {using System;using CNBlogs.DesignPattern.Common;class Program{static void Main(string[] args){ICar car;try{Factory factory = new Factory();Console.WriteLine("范·迪塞尔下一场戏开跑车。");car = factory.GetCar(CarType.SportCarType);car.GetCar();}catch (Exception ex){Console.WriteLine(ex.Message);}}} }
简单工厂的简单案例就这么多,真正在项目实战的话可能还有需要改进和扩展的地方。因需求而定吧。
6.简单工厂的优点/缺点:
- 优点:简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
- 缺点:很明显工厂类集中了所有实例的创建逻辑,容易违反GRASPR的高内聚的责任分配原则
1.介绍:
2.定义:
3.延伸:
4.模拟场景:
5.工厂方法UML类图: (UML图是我用windows自带的paint手工画的,所以可能不是很专业
6.代码演示:
抽象工厂代码:
namespace CNBlogs.DesignPattern.Common {public interface IFactory{ICar CreateCar();} }
抽象产品代码:
namespace CNBlogs.DesignPattern.Common {public interface ICar{void GetCar();} }
具体工厂代码:
namespace CNBlogs.DesignPattern.Common {/// <summary>/// 具体工厂类: 用于创建跑车类/// </summary>public class SportFactory : IFactory{public ICar CreateCar(){return new SportCar();}}/// <summary>/// 具体工厂类: 用于创建越野车类/// </summary>public class JeepFactory : IFactory{public ICar CreateCar(){return new JeepCar();}}/// <summary>/// 具体工厂类: 用于创建两厢车类/// </summary>public class HatchbackFactory : IFactory{public ICar CreateCar(){return new HatchbackCar();}} }
具体产品代码:
namespace CNBlogs.DesignPattern.Common {/// <summary>/// 具体产品类: 跑车/// </summary>public class SportCar : ICar{public void GetCar(){Console.WriteLine("场务把跑车交给范·迪塞尔");}}/// <summary>/// 具体产品类: 越野车/// </summary>public class JeepCar : ICar{public void GetCar(){Console.WriteLine("场务把越野车交给范·迪塞尔");}}/// <summary>/// 具体产品类: 两箱车/// </summary>public class HatchbackCar : ICar{public void GetCar(){Console.WriteLine("场务把两箱车交给范·迪塞尔");}} }
客户端代码:
//------------------------------------------------------------------------------ // <copyright file="Program.cs" company="CNBlogs Corporation"> // Copyright (C) 2015-2016 All Rights Reserved // 原博文地址: http://www.cnblogs.com/toutou/ // 作 者: 请叫我头头哥 // </copyright> //------------------------------------------------------------------------------ namespace CNBlogs.DesignPattern {using System.IO;using System.Configuration;using System.Reflection;using CNBlogs.DesignPattern.Common;class Program{static void Main(string[] args){// 工厂类的类名写在配置文件中可以方便以后修改string factoryType = ConfigurationManager.AppSettings["FactoryType"];// 这里把DLL配置在数据库是因为以后数据可能发生改变// 比如说现在的数据是从sql server取的,以后需要从oracle取的话只需要添加一个访问oracle数据库的工程就行了string dllName = ConfigurationManager.AppSettings["DllName"];// 利用.NET提供的反射可以根据类名来创建它的实例,非常方便var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly();string codeBase = currentAssembly.CodeBase.ToLower().Replace(currentAssembly.ManifestModule.Name.ToLower(), string.Empty);IFactory factory = Assembly.LoadFrom(Path.Combine(codeBase, dllName)).CreateInstance(factoryType) as IFactory;ICar car = factory.CreateCar();car.GetCar();}} }
7.工厂方法的优点/缺点:
- 优点:
- 子类提供挂钩。基类为工厂方法提供缺省实现,子类可以重写新的实现,也可以继承父类的实现。-- 加一层间接性,增加了灵活性
- 屏蔽产品类。产品类的实现如何变化,调用者都不需要关心,只需关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化。
- 典型的解耦框架。高层模块只需要知道产品的抽象类,其他的实现类都不需要关心,符合迪米特法则,符合依赖倒置原则,符合里氏替换原则。
- 多态性:客户代码可以做到与特定应用无关,适用于任何实体类。
- 缺点:需要Creator和相应的子类作为factory method的载体,如果应用模型确实需要creator和子类存在,则很好;否则的话,需要增加一个类层次。(不过说这个缺点好像有点吹毛求疵了)
1.介绍:
2.定义:
3.模拟场景:
4.场景分析:
上面的场景可能有点稀里糊涂的,但是用OO的思想结合前面的简单工厂和工厂方法的思路去理解的话,也好理解。
下面让我们来捋一捋这个思路:
- 抽象工厂:虚拟的车库,只是所有车库的一个概念。在程序中可能是一个借口或者抽象类,对其他车库的规范,开车和取包。
- 具体工厂:具体存在的车库,用来存放车和车对应的背包。在程序中继承抽象工厂,实现抽象工厂中的方法,可以有具体的产品。
- 抽象产品:虚拟的装备(车和对应的背包),也只是所有装备的一个概念。在程序中可能是多个接口或者多个抽象类,对具体的装备起到规范。
- 具体产品:活动参加的具体装备,它指的是组成装备的某一辆车或者背包。它继承自某一个抽象产品。
5.抽象工厂UML类图: (UML图是我用windows自带的paint手工画的,所以可能不是很专业)
6.代码演示:
抽象工厂代码:
namespace CNBlogs.DesignPattern.Common {/// <summary>/// 抽象工厂类/// </summary>public abstract class AbstractEquipment{/// <summary>/// 抽象方法: 创建一辆车/// </summary>/// <returns></returns>public abstract AbstractCar CreateCar();/// <summary>/// 抽象方法: 创建背包/// </summary>/// <returns></returns>public abstract AbstractBackpack CreateBackpack();} }
抽象产品代码:
namespace CNBlogs.DesignPattern.Common {/// <summary>/// 抽象产品: 车抽象类/// </summary>public abstract class AbstractCar{/// <summary>/// 车的类型属性/// </summary>public abstract string Type{get;}/// <summary>/// 车的颜色属性/// </summary>public abstract string Color{get;}}/// <summary>/// 抽象产品: 背包抽象类/// </summary>public abstract class AbstractBackpack{/// <summary>/// 包的类型属性/// </summary>public abstract string Type{get;}/// <summary>/// 包的颜色属性/// </summary>public abstract string Color{get;}} }
具体工厂代码:
namespace CNBlogs.DesignPattern.Common {/// <summary>/// 运动装备/// </summary>public class SportEquipment : AbstractEquipment{public override AbstractCar CreateCar(){return new SportCar();}public override AbstractBackpack CreateBackpack(){return new SportBackpack();}}/// <summary>/// 越野装备 这里就不添加了,同运动装备一个原理,demo里只演示一个,实际项目中可以按需添加/// </summary>//public class JeepEquipment : AbstractEquipment//{// public override AbstractCar CreateCar()// {// return new JeeptCar();// }// public override AbstractBackpack CreateBackpack()// {// return new JeepBackpack();// }//} }
具体产品代码:
namespace CNBlogs.DesignPattern.Common {/// <summary>/// 跑车/// </summary>public class SportCar : AbstractCar{private string type = "Sport";private string color = "Red";/// <summary>/// 重写基类的Type属性/// </summary>public override string Type{get{return type;}}/// <summary>/// 重写基类的Color属性/// </summary>public override string Color{get{return color;}}}/// <summary>/// 运动背包/// </summary>public class SportBackpack : AbstractBackpack{private string type = "Sport";private string color = "Red";/// <summary>/// 重写基类的Type属性/// </summary>public override string Type{get{return type;}}/// <summary>/// 重写基类的Color属性/// </summary>public override string Color{get{return color;}}} } //具体产品可以有很多很多, 至于越野类的具体产品这里就不列出来了。
创建装备代码:
namespace CNBlogs.DesignPattern.Common {public class CreateEquipment{private AbstractCar fanCar;private AbstractBackpack fanBackpack;public CreateEquipment(AbstractEquipment equipment){fanCar = equipment.CreateCar();fanBackpack = equipment.CreateBackpack();}public void ReadyEquipment(){Console.WriteLine(string.Format("老范背着{0}色{1}包开着{2}色{3}车。", fanBackpack.Color, fanBackpack.Type,fanCar.Color,fanCar.Type));}} }
客户端代码:
//------------------------------------------------------------------------------ // <copyright file="Program.cs" company="CNBlogs Corporation"> // Copyright (C) 2015-2016 All Rights Reserved // 原博文地址: http://www.cnblogs.com/toutou/ // 作 者: 请叫我头头哥 // </copyright> //------------------------------------------------------------------------------ namespace CNBlogs.DesignPattern {using System;using System.Configuration;using System.Reflection;using CNBlogs.DesignPattern.Common;class Program{static void Main(string[] args){// ***具体app.config配置如下*** ////<add key="assemblyName" value="CNBlogs.DesignPattern.Common"/>//<add key="nameSpaceName" value="CNBlogs.DesignPattern.Common"/>//<add key="typename" value="SportEquipment"/>// 创建一个工厂类的实例string assemblyName = ConfigurationManager.AppSettings["assemblyName"];string fullTypeName = string.Concat(ConfigurationManager.AppSettings["nameSpaceName"], ".", ConfigurationManager.AppSettings["typename"]);AbstractEquipment factory = (AbstractEquipment)Assembly.Load(assemblyName).CreateInstance(fullTypeName);CreateEquipment equipment = new CreateEquipment(factory);equipment.ReadyEquipment();Console.Read();}} }
抽象工厂模式符合了六大原则中的开闭原则、里氏代换原则、依赖倒转原则等等
7.抽象工厂的优点/缺点:
- 优点:
- 抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建。
- 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
- 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
- 缺点:增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。(不过说这个缺点好像有点吹毛求疵了)
这篇博文从晚上下班7点到家一直写到现在,说了一晚上的工厂,也扯了一晚上的速度与激情,在本博文完结的最后,给大家来一张速度与激情的画面精彩照。(ps:是不是觉得这种画面再配上一曲DJ一瓶啤酒会更嗨啊?哈哈...)
我们使用设计模式目的无非只有三个:a)缩短开发时间;b)降低维护成本;c)在应用程序之间和内部轻松集成。具体什么时候使用何种设计模式还得因项目而异。之所以对设计模式旧调重弹只是希望这个博文能对自己的架构之路有所提升,同时如果能帮助到其他人那就更完美了。
转载于:https://www.cnblogs.com/wobuchifanqie/p/10814929.html
设计模式学习02:简单工厂模式、工厂模式以及抽象工厂模式(具体)相关推荐
- 设计模式学习总结1 - 创建型1 - Abstract Factory抽象工厂模式
AbstractFactory抽象工厂模式(创建型) 作用: 这种模式支持创建不同的对象,这些对象功能接近且一般都是在一起创建的.抽象工厂被具体化成不同的工厂来创建类似产品的不同产品.这种模式将类于使 ...
- Java设计模式学习02——工厂模式
工厂模式 工厂模式主要是为创建对象提供接口,将创建对象的过程隔离起来,实现了创建者与调用者的分离,提高了程序的灵活性. 核心本质: 实例化对象,用工厂方法代替new操作. 将选择实现类.创建对象统一 ...
- Java设计模式-工厂模式(3)抽象工厂模式
在Java设计模式-工厂模式(2)工厂方法模式 我们知道了工厂方法模式解决了简单工厂模式中的缺陷,做到了满足开闭原则,但是时代是进步的,进而又产生新的问题,工厂难道只能生产一种东西吗.我们所见到的工厂 ...
- 设计模式学习笔记(C++实现)(九)--组合模式
1.组合模式简介 英文名称 Composite 主要目的 该模式将对象组合成树形结构已表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 使用场景 1.当 ...
- 工厂模式三部曲之三_抽象工厂模式(附三部曲源码)
抽象工厂模式是对工厂模式的进一步抽象,是工厂模式中最为抽象和最具一般性的一种形态,提供了创建一系列相关或者相互依赖对象的接口,而无需指定他们的类型. 如果你对工厂模式还有些迷惑的,可以回顾下工厂模式的 ...
- 设计模式学习--------3.简单工厂模式学习
场景: 服务端编写API方法供客户端调用,需要将接口与实现分离,客户端不需要知道具体实现,高度解耦,面向接口的编程. 定义: 提供一个创建对象实例的功能,而无须关心其具体实现,被创建实例的类型可以是接 ...
- 设计模式总结四(外观模式、建造者模式、观察者模式和抽象工厂模式)
序 这么多天里,我已经读完了<大话设计模式>.放寒假了,没有了通过学业考试的重担,阅读技术书籍的时间页多出来了不少. 在今天我刚阅读了<kafka权威指南>的第一章,关于介绍k ...
- 【设计模式】11-15:迪米特拉(最小知识)原则、外观模式、建造者模式、观察者模式、抽象工厂模式...
十一.迪米特拉原则/最小知识原则 如果两个类直接进行通信,那么这两个类就不能存在关系 调用其他类的方法时,需要第三个类实现转发-->外观类 尽量降低类的访问权限 十二.外观模式 隐藏系统的复杂性 ...
- 设计模式、原则、饿汉式单例模式、抽象工厂、代理模式、观察者模式、模板方法模式使用场景
设计模式 对各种面向对象方法的一种总结.前辈们遇到了好多设计问题,然后利用面向对象解决了.然后他们把解决方案汇总起来,形成了20多种设计模式.它可以有效的帮助我们利用面向对象,来提高代码的复用性. ...
- 设计模式【2.2】-- 工厂模式怎么演变成抽象工厂模式?
还记得之前的工厂方法模式么?现在老板更加富有了,除了水果,还准备搞点其他的生意,再做点服装生意.水果工厂和服装工厂明显就不是同一种东西,肯定不能放到一个工厂里面生产,服装也有好几种,但是不同的工厂,也 ...
最新文章
- python有哪些作用-Python中的NumPy是什么?有什么作用?
- 打开Mybatis核心配置文件SqlMapConfig.xml的代码提示功能
- 360安全卫士电脑版_教你降服“流氓头子”正确打开360安全卫士的姿势,还你电脑流畅体验...
- cdockpane限制调整大小_影视后期制作小伙伴必看:使用AU对声音质量进行调整的三大技巧...
- 基于D3.js实现分类多标签的Tree型结构可视化
- Linux下单独编译安装PHP扩展包
- jquery 动画总结(主要指效果函数)
- REST+EJB+JPA 框架在 Eclipse+TomEE 的开发环境搭建
- 超频到3200最佳时序_内存条从入门到精通!想要超频或是稳定,看完保证你也能轻松挑选...
- 闰年2月29号 通过apache的ftp工具从ftp上下载文件失败
- CSCD(2015-2016年)来源期刊目录中国科学引文数据库
- 图片处理-----毛玻璃效果
- win10睡眠模式 屏幕熄灭主机仍然运行
- C++的一个指针占内存几个字节?
- C#按汉字拼音首字母排序
- 本周解锁新技能:识简谱、弹音阶(2019 年 8 月 3日)
- 【回归预测-ELM预测】基于粒子群算法PSO优化极限学习机预测附matlab代码
- ASP.NET点餐系统源码(电脑手机通用)源代码分享
- 小数点怎么进行进制转换?
- 【转】李想:关于工作和成长,这是我的100条具体建议 |【经纬低调分享】
热门文章
- 构建之法1,5,17章学习心得
- 查看Linux是Redhat 还是centos 还是...
- Windows环境下log4cxx的编译及使用(转载)
- BootStrap布局案例
- C# delegate ,Action,Func
- 基于互信息的特征选择算法MATLAB实现
- 机器学习第六回——无监督学习
- Java通过微信公众号获取地理位置信息
- 服务器iis限制ip访问网站吗,利用IIS实现网站后台IP登录限制
- 计算机操作员(高级)理论知识考试卷,计算机操作员高级试题