单例模式
本博客大部分内容来于免费在线学习设计模式 1:单例模式单例模式是一种创建型设计模式,让你能够保证一个类只有一个实例,并提供一个访问该实例的全局节点。 2:单例模式问题单例模式同时解决了两个问题。所以违反了单一职责原则。 保证一个类只有一个实例。(eg:控制某些共享资源 (例如数据库或文件) 的访问权限。) 为该实例提供一个全局访问节点。 例如存储重要对象的全局变量,它们在使用上十分方便,但同时也非常不安全,因为任何代码都有可能覆盖掉那些变量的内容,从而引发程序崩溃。 例:一个国家只有一个政府,不管身份是什么,而”某政府“就像全局访问节点一样。 3:单理模式结构 单例 (Singleton) 类声明了一个名为 getInstance获取实例的静态方法来返回其所属类的一个相同实例。 单例的构造函数必须对客户端 (Client) 代码隐藏。调用 获取实例方法必须是获取单例对象的唯一方式。 代码示例: 单例模式有多种创建方法: 这里列举三种: 通过枚举类型创建单例 12345public enum Singleton { INSTANCE; ...
抽象工厂模式
本博客大部分内容来于免费在线学习设计模式 1:抽象工厂模式抽象工厂(AbstractFactory)模式是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。 2:抽象工厂模式问题工厂方法模式考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养计算机软件专业的学生等。 但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品,如农场里既养动物又种植物,电器厂既生产电视机又生产洗衣机或空调,大学既有软件专业又有生物专业等。 而抽象工厂模式将考虑多等级产品的生产。将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族, 3:抽象工厂模式解决方案首先,抽象工厂模式建议为系列中的每件产品明确声明接口。然后确保所有产品变体都继承这些接口,例如(所有品牌的电视机都继承电视机接口,所有品牌的空调都继承空调接口) 然后声明抽象工厂–包含系列中所有产品构造方法的接口。例如:createWasher(创建洗衣机),createTV(创建电视机)…这些方法必须返回抽象产品类型...
原型模式
本博客大部分内容来于免费在线学习设计模式 1:原型模式原型模式是一种创建型设计模式,使你能够复制已有对象,而又无需使代码依赖它们所属的类。 2:原型模式问题如果你有一个对象,并希望生成与其完全相同的一个复制品,你该如何实现呢?首先,你必须新建一个属于相同类的对象。然后,你必须遍历原始对象的所有成员变量,并将成员变量值复制到新对象中。 但是并非所有对象都能通过这种方式进行复制, 因为有些对象可能拥有私有成员变量, 它们在对象本身以外是不可见的。 3:原型模式解决方法用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。例如,Windows 操作系统的安装通常较耗时,如果复制就快了很多。在生活中复制的例子非常多,这里不一一列举了。 4:原型模式解决方案 原型 (Prototype) 接口将对克隆方法进行声明。 在绝大多数情况下, 其中只会有一个名为 clone克隆的方法。 具体原型 (Concrete Prototype) 类将实现克隆方法。 除了将原...
生成器模式
本博客大部分内容来于免费在线学习设计模式 1:生成器模式生成器模式是一种创建型设计模式,使你能够分步骤创建复杂对象。该模式允许你使用相同的创建代码生成不同类型和形式的对象。 2:生成器模式问题在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。例如,计算机是由 OPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。生活中这样的例子很多,如游戏中的不同角色,其性别、个性、能力、脸型、体型、服装、发型等特性都有所差异;还有汽车中的方向盘、发动机、车架、轮胎等部件也多种多样;每封电子邮件的发件人、收件人、主题、内容、附件等内容也各不相同。 解决这些问题最简单的方法是扩展基类,然后创建一系列覆盖所有参数组合的子类。但最终你将面对相当数量的子类。任何新增的参数都会让这个层次结构更加复杂。 另一种方法则无需生成子类。你可以在房屋基类中创建一个包括所有可能参数的超级构造函数,并用它来控制房...
工厂方法模式
本博客大部分内容来于免费在线学习设计模式 1:工厂方法模式工厂方法模式是一种创建型设计模式,其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。 2:工厂方法模式问题举个例子:假如你现在需要不同类型的水果:例如苹果,香蕉,梨等等。现在如果没有淘宝,水果摊这一类能提供多种水果的“工厂”。那么你买苹果需要去找苹果园,买香蕉需要去找香蕉生产地,每一个水果都需要你自行联系对应的水果生成地。很麻烦不是吗,想一想水果摊这一类的“工厂”是怎么解决这问题的? 再举一个例子: 如果你开发了一款物流管理应用。假设每一种运输方法类的构建都很复杂,需要编写大量代码。在初始版本只支持一种运输方案:卡车,于是你选择直接调用多个方法来创建卡车类。后来你需要增加另一个方式:轮船。代码部分该如何处理呢?继续直接创建一个轮船类吗。那么创建轮船类的大量代码将到处都是。更糟糕的是,如果你以后需要在程序中支持另外一种运输方式,很可能需要再次对这些代码进行大幅修改。 最后,你将不得不编写繁复的代码,根据不同的运输对象类,在应用中进行不同的处理。 3:工厂方法模式解决方案工厂方法模式建议使用特殊的工厂方法代替...
命令模式
本博客大部分内容来于免费在线学习设计模式 1:命令模式命令模式是一种行为设计模式, 它可将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据不同的请求将方法参数化、 延迟请求执行或将其放入队列中, 且能实现可撤销操作。 2:命令模式问题假如你当前有一个列表页面需要渲染,当页面加载时需要请求数据,点击重置按钮时也需要请求页面数据,搜索数据也可以根据这个接口来请求数据。那么你怎么处理呢?是将数据的实现类复制多次,还是用其他方法呢? 3:命令模式解决方案很显然,在我们的实际使用中,是将数据请求和数据实现分离。将请求的所有细节(例如调用的对象、方法名称和参数列表)抽取出来组成命令类,该类中仅包含一个用于触发请求的方法。 在现实生活中,命令模式的例子也很多。比如看电视时,我们只需要轻轻一按遥控器就能完成频道的切换,这就是命令模式,将换台请求和换台处理完全解耦了。电视机遥控器(命令发送者)通过按钮(具体命令)来遥控电视机(命令接收者)。 再比如,我们去餐厅吃饭,菜单不是等到客人来了之后才定制的,而是已经预先配置好的。这样,客人来了就只需要点菜,而不是任由客人临时定制。餐...
观察者模式
本博客大部分内容来于免费在线学习设计模式 1:观察者模式观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个“观察”该对象的其他对象。 2:观察者模式问题在现实世界中,许多对象并不是独立存在的,其中一个对象的行为发生改变可能会导致一个或者多个其他对象的行为也发生改变。拿双十一举例:如果某一商品决定在双十一当天零点进行大促销,如果他选择不通知任何人,那么他这一件商品的销量就只有听天由命了,一件都卖不去也说停;如果他选择通知所有浏览过这件商品的人,也许在这些人里有想买这件商品的人会选择购买,但是也会有很多不需要这件商品的人收到骚扰。在生活中,他们是怎么解决这件事的呢? 3:观察者模式解决方案在生活中,这些购物软件给店铺提供了一个渠道:对于那些关注过这家店铺,或者在这家店铺购买过的商品的潜在用户。店家可以通过软件提供的消息推送方式,或者购买记录的个人信息(虽然各种短信也挺骚扰的)。告诉你:我要降价了,快来买哦。这样店家也达成通知用户提高销量的目的,买家也可以低价买入需要的物品。 观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一...
责任链模式
本博客大部分内容来于免费在线学习设计模式 1:责任链模式责任链模式是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。 2:责任链模式问题在日常生活中,请假,出差,申请活动等等。一件事可能需要经过多个对象的处理。举个例子:你写了一个办公程序,最初设置的是只需要部门主管同意,后面又逐渐增加人事,领导等等很多步骤。现在需要另外增加另一项功能,也需要这些审批手续(也可能是部分)。这一段代码怎么写呢?直接复制代码吗,本来每次增加步骤都会使代码更加臃肿,再对这些臃肿的代码进行复制,系统会变成怎样呢? 3:责任链模式解决方案责任链会将特定行为转换为被称作处理者的独立对象。在上述示例中,每个审批步骤都可被抽取为仅有单个方法的类,并执行审批操作。 请求及其数据则会被作为参数传递给该方法。 模式建议你将这些处理者连成一条链。链上的每个处理者都有一个成员变量来保存对于下一处理者的引用。除了处理请求外,处理者还负责沿着链传递请求。请求会在链上移动,直至所有处理者都有机会对其进行处理。 最重要的是:处理者可以决定不再沿着链传递...
迭代器模式
本博客大部分内容来于免费在线学习设计模式 1:迭代器模式迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式(列表、栈和树等)的情况下遍历集合中所有的元素。 2:迭代器模式问题在现实生活以及程序设计中,经常要访问一个聚合对象中的各个元素,如“数据结构”中的链表遍历,通常的做法是将链表的创建和遍历都放在同一个类中,但这种方式不利于程序的扩展,如果要更换遍历方法就必须修改程序源代码,这违背了 “开闭原则”。而且不断向集合中添加遍历算法会模糊其 “高效存储数据” 的主要职责。 此外, 有些算法可能是根据特定应用订制的, 将其加入泛型集合类中会显得非常奇怪。 另一方面, 使用多种集合的客户端代码可能并不关心存储数据的方式。 不过由于集合提供不同的元素访问方式, 你的代码将不得不与特定集合类进行耦合。 既然将遍历方法封装在聚合类中不可取,那么聚合类中不提供遍历方法,将遍历方法由用户自己实现是否可行呢?答案是同样不可取,因为这种方式会存在两个缺点: 暴露了聚合类的内部表示,使其数据不安全; 增加了客户的负担。 3:迭代器模式解决方案迭代器模式的主要思想是将集合的遍历行为抽取...
享元模式
本博客大部分内容来于免费在线学习设计模式 1:享元模式享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。 2:享元模式问题在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题。创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈。例如,围棋和五子棋中的黑白棋子,图像中的坐标点或颜色,局域网中的路由器、交换机和集线器,教室里的桌子和凳子等。这些对象有很多相似的地方,如果能把它们相同的部分提取出来共享,则能节省大量的系统资源,这就是享元模式的产生背景。 3:享元模式解决方案在黑白棋子,坐标点这些类中,你会发现一些成员变量储存的值是相同的,而每个粒子的另一些状态(坐标,颜色等)是不同的。 对象的常量数据通常被称为内在状态(即不会随着环境的改变而改变的可共享部分), 其位于对象中,其他对象只能读取但不能修改其数值。而对象的其他状态常常能被其他对象 “从外部” 改变,因此被称为外在状态(随环境改变而改变的不可以共享的部分)。 享元模式建议不在对象中存储外在状...