因为代码比较多,可以下载设计模式案例代码查看,以上是设计模式代码的案例目录
代码下载
一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分(There should never be more than one reason for a class to change)
简单来说指的是每个类只负责自己的事情,而不是变成万能
软件实体应当对扩展开放,对修改关闭(Software entities should be open for extension,but closed for modification),简单来说指的是扩展新类而不是修改旧类
。
合成复用原则、里氏替换原则相辅相成,都是开闭原则的具体实现规范。
继承必须确保超类所拥有的性质在子类中仍然成立(Inheritance should ensure that any property proved about supertype objects also holds for subtype objects)
简单来说指的是继承父类而不去改变父类
.
高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象(High level modules shouldnot depend upon low level modules.Both should depend upon abstractions.Abstractions should not depend upon details. Details should depend upon abstractions)
简单来说指的是面向接口编程,而不是面向实现类
一个类对另一个类的依赖应该建立在最小的接口上(The dependency of one class to another one should depend on the smallest possible interface)。
简单来说指的是各个类建立自己的专用接口,而不是建立万能接口
最少知识原则(Least Knowledge Principle,LKP),只与你的直接朋友交谈,不跟“陌生人”说话(Talk only to your immediate friends and not to strangers)
简单来说指的是无需直接交互的两个类,如果需要交互,使用中间者
过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低
又叫组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP)
软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现
简单来说指的是优先组合,其次继承
创建型模式关注点“怎样创建出对象?
“将对象的创建与使用分离”,降低系统的耦合度,使用者无需关注对象的创建细节
一个单一的类,负责创建自己的对象,同时确保系统中只有单个对象被创建。
package com.atation.singleton;/*** boss只能有一个*/
public class Person {private String name;private String age;//懒汉、饿汉private volatile static Person instance; //饿汉//构造器私有,外部不能实例化private Person() {System.out.println("创建了Person");}//提供给外部的方法//1、public static synchronized Person guiguBoss() 锁太大//2、双重检查锁+内存可见性(设计模式)public static Person guiguBoss() {//如果没有再去创建if (instance == null) {synchronized (Person.class) {if(instance == null){Person person = new Person();//多线程问题instance = person;}}}return instance;}
}
package com.atation.singleton;
public class MainTest {public static void main(String[] args) {Person person1 = Person.guiguBoss();Person person2 = Person.guiguBoss();System.out.println(person1 == person2);}
}
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。本体给外部提供一个克隆体进行使用
将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。
package com.atation.prototype;
import java.util.HashMap;
import java.util.Map;
public class GuiguMybatis {//缓存user.序列化和反序列化-深克隆private Map<String,User> userCache = new HashMap<>();/*** 从数据库查数据* @return*/public User getUser(String username) throws Exception {User user = null;//缓存中没有if(!ainsKey(username)){//查询数据库user = getUserFromDb(username);}else {//从缓存中直接拿,脏缓存问题//原型已经拿到,但是不能直接给。(本人)user = (username);System.out.println("从缓存中拿到的是:"+user);//从这个对象快速得到一个克隆体(克隆人)==原型模式user = (User) user.clone();}return user;}private User getUserFromDb(String username) throws Exception{System.out.println("从数据库查到:"+username);User user = new User();user.setUsername(username);user.setAge(18);//给缓存中放一个cloneuserCache.put(username, (User) user.clone());return user;}
}
package com.atation.prototype;import lombok.Data;/*** 当前对象是可克隆的*/
@Data
public class User implements Cloneable {private String username;private Integer age;/*** 再创建一个人,赋予我的所有属性* @return* @throws CloneNotSupportedException*/@Overrideprotected Object clone() throws CloneNotSupportedException {User user = new User();user.setUsername(username);user.setAge(age);return user;}
}
package com.atation.prototype;/*** 是用于创建重复的对象,同时又能保证性能。* 1、GuiguMyBatis:操作数据库,从数据库里面查出很多记录(70%改变很少)* 2、每次查数据库,查到以后把所有数据都封装一个对象,返回。* 10000 thread:查一个记录: new User("zhangsan",18);每次创建一个对象封装并返回* 系统里面就会有10000个User;浪费内存* 3、解决:缓存;查过的保存。* 如果再查相同的记录,拿到原来的原型对象** 4、此时直接拿到缓存中的对象。***/
public class MainTest {public static void main(String[] args) throws Exception {GuiguMybatis mybatis = new GuiguMybatis();//十分危险//得到的是克隆体User zhangsan1 = User("zhangsan");System.out.println("1==>"+zhangsan1);zhangsan1.setUsername("李四2.。。");System.out.println("zhangsan1自己改了:"+zhangsan1);//得到的是克隆体User zhangsan2 = User("zhangsan");System.out.println("2-->"+zhangsan2);//得到的是克隆体User zhangsan3 = User("zhangsan");System.out.println("3-->"+zhangsan3);//得到的是克隆体User zhangsan4 = User("zhangsan");System.out.println("4-->"+zhangsan4);System.out.println(zhangsan1 == zhangsan3);}
}
三个角色
缺点:违背开闭,扩展不易
package com.atation.factory.simplefactory;/*** 简单工厂* 1、产品数量极少*/
public class WuLinSimpleFactory {/**** @param type Class: 好像具有扩展性,但是没有解决实际问题* @return*/public AbstractCar newCar(String type){//核心方法:一切从简if("van".equals(type)){// 钣金、喷漆、放发动机、申请环保return new VanCar();}else if("mini".equals(type)){return new MiniCar();}//.....//更多的产品,违反开闭原则。应该直接扩展出一个类来造return null;}
}
package com.atation.factory.simplefactory;/*** 工厂的产品*/
public abstract class AbstractCar {String engine;public abstract void run();
}
package com.atation.factory.simplefactory;public class MiniCar extends AbstractCar{public MiniCar(){ine = "四缸水平对置发动机";}@Overridepublic void run() {System.out.println(engine+"--> 嘟嘟嘟...");}
}
package com.atation.factory.simplefactory;/*** 具体产品*/
public class VanCar extends AbstractCar{public VanCar(){ine = "单杠柴油机";}@Overridepublic void run() {System.out.println(engine+"--》嗒嗒嗒....");}
}
package com.atation.factory.simplefactory;public class MainTest {public static void main(String[] args) {WuLinSimpleFactory factory = new WuLinSimpleFactory();AbstractCar van = wCar("van");AbstractCar mini = wCar("mini");van.run();mini.run();}
}
四个角色
缺点:系统复杂度增加,产品单一
代码实现
提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。
代码实现
将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。
代码实现
结构型模式关注点“怎样组合对象/类?”所以我们关注下类的组合关系
类结构型模式关心类的组合
,由多个类可以组合成一个更大的(继承)对象结构型模式关心类与对象的组合
,通过关联关系在一个类中定义另一个类的实例对象(组合)根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式。
代理模式(Proxy Pattern) ,给某一个对象提供一个代理,并由代理对象控制对原对象的引用,对象结构型模式。这种也是静态代理,一个静态代理只能代理一个对象,比方说代理person,或者代理cat,而动态代理可以代理多个对象,根据传的不同对象生成不同的代理对象。具体实现可以在代码中查看。
代理模式包含如下角色:
代码实现
将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,适配器模式分为类结构型模式(继承)和对象结构型模式(组合)两种,前者(继承)类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
适配器模式(Adapter)包含以下主要角色。
代码实现
将抽象与实现解耦,使两者都可以独立变化
,在现实生活中,某些类具有两个或多个维度的变化,如图形既可按形状分,又可按颜色分。如何设计类似于 Photoshop 这样的软件,能画不同形状和不同颜色的图形呢?如果用继承方式,m 种形状和 n 种颜色的图形就有 m×n 种,不但对应的子类很多,而且扩展困难。不同颜色和字体的文字、不同品牌和功率的汽车
桥接将继承转为关联,降低类之间的耦合度,减少代码量
桥接(Bridge)模式包含以下主要角色。
代码实现
向一个现有的对象添加新的功能,同时又不改变其结构。属于对象结构型模式。
创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
代码实现
外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式
代码实现
享元模式(Flyweight Pattern),运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。
对象结构型在享元模式中可以共享的相同内容称为内部状态(IntrinsicState),而那些需要外部环境来设置的不能共享的内容称为外部状态(Extrinsic State),由于区分了内部状态和外部状态,因此可以通过设置不同的外部状态使得相同的对象可以具有一些不同的特征,而相同的内部状态是可以共享的。
在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池(Flyweight Pool)用于存储具有相同内部状态的享元对象。
享元模式包含如下角色:
代码实现
相似对象进行组合,形成树形结构
代码实现
使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。结合多个标准来获得单一标准
代码实现
过滤器模式
行为型模式关注点“怎样运行对象/类?”所以我们关注下类/对象的运行时流程控制
行为型模式用于描述程序在运行时复杂的流程控制
,描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务
,它涉及算法与对象间职责的分配。
行为型模式分为类行为模式
和对象行为模式
,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。
由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。
在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
模板方法(Template Method)包含两个角色
代码实现
策略(Strategy)模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。属于对象行为模式。
策略模式的主要角色如下。
代码实现
命令(Command)模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
命令模式包含以下主要角色。
代码实现
责任链(Chain of Responsibility)模式:为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。属于对象行为型模式
代码实现
状态(State)模式:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
状态模式包含以下主要角色。
代码实现
观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。对象行为型模式
代码实现
中介者模式(Mediator Pattern):用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,减少对象间混乱的依赖关系,从而使其耦合松散,而且可以独立地改变它们之间的交互。对象行为型模式。
代码实现
迭代器(Iterator)模式:提供一个对象(迭代器)来顺序访问聚合对象(迭代数据)中的一系列数据,而不暴露聚合对象的内部表示。对象行为型模式
代码实现
访问者(Visitor)模式:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。
代码实现
备忘录(Memento)模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。对象行为型模式
代码实现
解释器(Interpreter)模式:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。类行为型模式
代码实现
本文发布于:2024-01-27 17:01:52,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17063461101527.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |