关于编程设计模式的简介

3 篇文章 0 订阅

编程设计模式

简介:编程设计模式,是软件开发人员在长期软件开发过程中常面临的一般问题解决方案的整合。
出自四人帮(Gang of Four)合著出版的一本名为《Design Patterns - Elements of Reusable Object-Oriented Software》(中文译名:设计模式 - 可复用的面向对象软件元素) 的书。

一:创建模式(Creational Patterns)

1.工厂模式(Factory Pattern)

定义一个工厂生产者对象(内部封装创建指定类型实例的函数),根据表示(className)创建对应的对象,并返回该对象,让使用者调用指定的方法。

2.抽象工厂模式(Abstract Factory Pattern)

将多个工厂生产对象,抽象成一个高级工厂生产对象,通过这个高级工厂生产对象,调用工厂对象创建具体的对象,并返回,共使用者调用指定方法。

3.单例模式(Singleton Pattern)

单例模式是保证只有一个实例被创建的设计模式,主要特点是:私有化构造器、提供一个统一获取实例的函数。
单例设计模式主要是希望减少内存的开销。有6种实现方式,又分为线程安全型和线程非安全型。

 1.懒汉式不加锁(性能优,线程不安全),
 2.懒汉式加锁(函数上加锁,性能稍差,线程安全),
 3.双重判定加锁(函数内部实现加锁,性能优,线程安全)【推荐】,
 4.饿汉式(性能优,线程安全,消耗内存,长时间不使用容易产生资源浪费)
 5.登记式/静态内部类(性能优,线程安全)【推荐】
//登记式/静态内部类
public class Singleton {  
    private static class SingletonHolder {  
    private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
    return SingletonHolder.INSTANCE;  
    }  
}
 6.枚举方式
 (性能优,线程安全、非懒加载方式和饿汉式比较像,但比饿汉式简洁并支持屏蔽 reflection attack 方式来调用私有构造方法。)
//枚举方式
public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
} 
4.建造者模式(Builder Pattern)

通过接口和抽象化对象最终逐步构建复杂的对象,描述特定的业务场景。

优点:业务专一,易于扩展出相似的业务属性,提高代码复用率;
缺点:业务范围有限制性,不适合扩展多业务场景
5.原型模式(Prototype Pattern)

基于一个元对象通过克隆方式快速创建复用对象,对象的复用性高。

实现方式:需要实现Cloneable 接口,并复写clone()方法。如果希望实现深度拷贝可以通过实现Serializable存取序列化二进制流。

使用场景:优化频繁创建获取的资源,将数据实例化或对象序列化,一次创建后可以反复多次克隆复制。

二:结构型模式(Structural Patterns)

1.适配器模式(Adapter Pattern)

把2个已经存在但无关紧要的不兼容接口,通过继承或依赖方式进行属性和方法的集成,使得该集成对象可以调用并使用这2个接口。

使用场景:在正在服役的项目中有动机地改造或扩展一个正常运行的系统的接口

优点:1.集成2个无关联但业务相近的类功能。2.提高类的复用。3.增加类的透明度。4.灵活调用
缺点:过多的使用适配器,容易使得系统混乱。不适用于多业务扩展和继承。
2.桥接模式(Bridge Pattern)

桥接模式是把抽象化对象与实现类解耦,使得二者可以独立变化。这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。

何使使用:主要解决在多种可能变化的情况下,使用继承回造成类爆炸问题,尽可能使扩展起来灵活。

优点:1.把抽象和现实分离。2.易于扩展。3.实现细节对客户透明
缺点:设计难度较大,需要抽象类依赖实现类。
3.过滤器模式(Filter、Criteria Pattern)

过滤器模式(Filter Pattern)或标准模式(Criteria Pattern),通过逻辑运算实现过滤一组对象,也可以结合多个过滤模型来获取单一的标准结果。

举例1:“课本科目归类过滤”,课本若干,课本可以归为:“必修”、“选修”,细分一层:“理科”、“文科”、“副科”,再细分一层:“理论型”,“操作型”。

	期望结果1:理论型的理科必修科目
	期望结果2:副科必修科目
	期望结果3:文科选修偏理论科目

举例2:“服饰过滤”,服饰物品若干,类型可归为:“春装”、“夏装”、“秋装”、“冬装”,也可归类为:“薄”、“厚”、“适中”,还可归类:“帽”,“上衣”、“裤子”、“裙子”、“鞋子”、“装饰”

	期望结果1:春装上衣裤子 薄厚适中
	期望结果2:夏装裙子薄款
4.组合模式(Composite Pattern)

组合模式又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。通过树形结构来组合对象,用于表示部分以及整体层次。

实现方式:树形结构,树枝和叶子实现统一接口,树枝内部组合该接口,并且含有内部属性List,里面存放子节点。

5.装饰器模式(Decorator Pattern)

装饰器模式允许向现有的对象添加新的功能,同时又不改变其结构,作为现有类的一个包装。

优点:这种设计模式使得装饰类和被装饰类可以独立发展,不会互相耦合,用于替代继承带来类爆炸的	耦合扩展方式。

实现:装饰类实现和被装饰类相似的函数,经过装饰类的方法调用对应的被装饰类方法,允许调用前后添加装饰类自己的实现方式。

应用场景:日志切面输出、扩展一个类的功能、动态添加功能和撤销功能。

6.外观模式(Facade Pattern)

外观模式目的是隐藏系统的复杂性,并向客户端提供可以访问系统的接口,对系统原有接口进行封装,客户端不需要关心系统的内部实现。

优点:1. 减少系统相互依赖。2. 提高灵活性。3. 提高安全性
缺点:不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
7.享元模式(Flyweight Pattern)

享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能。
享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新的对象。

缺点:实现难度较高,需要分离出外部状态属性和内部状态属性,否则容易引起线程安全性问题。必须有一个工厂类来实现控制。

实现:创建一个工厂类,内部通过Map对象存储“分离属性”的实体对象。通过输入属性标识,工厂类返回对应的实体对象。

案例:有一整套不同颜色的笔,先创建好笔的对象并存放在调用工厂的容器中,通过告诉工厂需要什么颜色的笔来获取对应的笔实体类。

8.代理模式(Proxy Pattern)

通过实现一个类来代表另一个类的功能,为其他对象提高一种代理以控制这个对象的访问。

应用实例:桌面程序“快捷方式”、spring aop面向切面思想、支票代理现金的交易、通过售票点代理窗口购票等。

注意事项:和装饰器模式、适配器模式都有点类似。和适配器模式区别:适配器注意改变所考虑对象的接口而代理模式不能改变代理类的接口。和装饰器模式区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

优点:高扩展性,使功能灵活化
缺点:代理的实现通常增加了内存开销,间接调用方式某些情况下(远程请求)还会影响处理速度。复杂化实现的可能。

三:行为型模式(Behavioral Patterns)

1.责任链模式(Chain of Responsibility Pattern)

责任链模式为请求创建了一个接收者对象链。这种模式给予请求类型,对象请求的发送者和接收者进行解耦。这种模式中,通常每个接收者都包含对另一个接收者的引用。如果对象不能处理改请求,那么它会把相同的请求传给下一个接收者,以此类推到最后处理的接收者处理这个请求。

优点:1.降低耦合度。它将请求的发送者和接收者解耦。
		  2.简化了对象,使得对象不需要知道链的结构。
		  3.增强了对象指派职责的灵活性。
缺点:1.不能保证请求一定被接收。
		  2.对系统性能的消耗有一定的影响。
		  3.出错时候不易于运行观察。

使用场景:

 1.有多个对象可以处理同一个请求,但不确定具体由谁来处理。
 2.在不明确指定接收者的情况下,向多个对象中的其中一个发一个请求。
 3.可动态指定一组对象处理请求。
2.命令模式(Command Pattern)

命令模式是一种数据驱动的设计模式,请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适对象,并把该命令再次传递给相应的对象,最终执行命令结束流程。

实现方式:首先创建作为传递执行命令的接口,由具体的命令执行者实现这个接口(若干个命令),定义一个容器List 的类管理这些命令,并提供依次执行列表命令的函数。

优点:降低了系统的耦合度,新的命令可以很灵活的添加到系统中
缺点:设计难度稍大,容易混乱
3.解释器模式(Interpreter Pattern)

解释器模式提供了评估语言的语法或表达式的方式,该模式实现了一个表达式接口,用于解释特定的上下文。这种模式被用在SQL解析、符号处理引擎等。

使用场景:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。用户只需要输入一串字符,就可对里面的文法进行解析判定。

4.迭代器模式(Iterator Pattern)

迭代器模式适用于顺序访问集合对象元素,不需要知道集合对象的底层表示。

关键代码:定义接口,提供hasNext和next函数。

优点:
	  1.支持以不同的方式遍历一个聚合对象。
	  2.迭代器简化了聚合类
	  3.在同一个聚合上可以有多个遍历
	  4.对于新增加的迭代器类和聚合类操作方便,不需要更改原有的代码
	  
缺点:由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,使得系统的复杂度增加。
5.中介者模式(Mediator Pattern)

中介者模式是用来降低多个对象和类之间的通信复杂度的。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使得代码易于维护。

何时使用:多个类相互耦合,形成网状结构。

优点:
	1.降低了类的复杂度,将一对多转化成了一对一
	2.各各类之间的解耦
	
缺点:类的增加中介者会变得庞大,有一定的性能消耗代价。
6.备忘录模式(Memento Pattern)

备忘录模式就是 保存一个对象的某个状态,以便在适当的时候恢复对象。

7.观察者模式(Observer Pattern)

当对象间存在一对多关系时候,则使用观察者模式。比如,当一个对象被修改时,则会通知它的依赖对象,让所有依赖它的对象得到通知并自动更新。

关键代码:在抽象类里设一个ArrayList容器用于存放观察者门,所有观察者都实现了共有的方法,且调用逻辑相同。

8.状态模式(State Pattern)

在状态模式中,类的行为是基于它的状态决定的。

主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态的改变而改变它的相关行为。

关键代码:通常命令模式的接口中只有一个方法。而状态模式的接口中有一个或多个方法。而且状态模式的实现类发方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。

优点:
1.封装了转换规则,
2.枚举可能的状态,
3.将所有与某个状态有关的行为放到一个类中,并且可以方便增加新的状态,只需要改变对象状态即可改变对象行为。

缺点:1.随着状态的增加必定会增加系统类和对象的个数。
		  2.实现难度较大。
		  3.状态模式对“开闭原则”的支持并不太好。
9.空对象模式(null of object Pattern)

在空对象模式中,一个空对象用于取代null对象实例的检查。空对象不是检查空值,而是反应一个不做任何动作的关系,这样的空对象也可以在数据不可用的时候提供默认的行为。

实现:空对象也是一个实现对象,可以被实例化,对于数据空时候做了特殊的处理。

10.策略模式(Strategy Pattern)

在策略模式中,一个类的行为或其算法可以在运行时更改。

主要解决:在有多种算法相似的情况下,定义一系列的算法具体实现,把他们一个个封装起来,并且使得它们可以相互替换。解决了过多的if…else 所带来的复杂和难以维护。

优点:1.算法可以自由切换,更灵活。2.避免使用多重条件判定。3.使得程序更具有扩展性。
缺点:策略类过多容易混乱,并且所有策略类都需要对外暴露。
11.模板模式(Template Pattern)

在模板模式中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按照需要重写方法实现,但调用将以抽象类中定义的方式进行。我们通常将这个执行方法在抽象类中定义为final,不让子类复写。

优点:1.封装不变部分,扩展可变部分。2.提前公共代码,便于维护。3.行为由父类控制,子类实现。
缺点:每一个不同的实现都需要一个字类来实现,导致个数的增加,使得系统变得庞大。
12.访问者模式(Visitor Pattern)

在访问者模式中,我们使用一个访问者类,由它来改变元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。将数据结构与数据操作分离,实现稳定的数据结构和易变的操作进行解耦。

何使使用:需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”这些对象的类,可以使用访问者模式将这些类封装到类中。

实现:在被访问者的类里面加一个对外提供接待访问者的接口,调用者将自身引用传入访问者。

优点:1.符号单一职责原则。2.优秀的扩展性。3.灵活性好

缺点:
	1.具体元素对访问者公布细节,违反了迪米特原则。
	2.具体元素的变更变得困难。
	3.违反了依赖倒置原则,依赖了具体类,没有依赖抽象类。

四:J2EE模式

1.MVC模式(MVC Pattern)

MVC代表:Model-View-Controller。这种模式运用于应用程序的分层开发。

Model(模型)- 代表一个存取数据的对象或 JAVA POJO。

View(视图)- 代表数据的可视化

Controller(控制器)- 作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。
2.业务代表模式(Business Delegate Pattern)

业务代表模式用于对表示层和业务层进行解耦,它基本上是用来减少通信或对表示层代码中的业务层代码的远程查询功能。

业务层中通常定义的实体:

客户端(Client)- 表示层代码可以是JSP、Servlet或UI java 代码

业务代表(Business Delegate)- 一个为客户端实体提供入口的类,它提供了对业务方法的访问。

查询服务(LookUp Service)- 查找服务对象负责获取相关的业务实现,并提供业务对象对业务代表对象的访问。

业务服务(Business Service)- 业务服务接口。实现了该业务服务的实体类,提供了实际业务的实现逻辑。
3.组合实体模式(Composite Entity Pattern)

组合实体模式用在EJB(Enterprise Java Bean)持久化机制中,一个组合代表了一个Bean实体,代表了对象的图解。当更新一个组合实体时,内部依赖对象Beans会自动更新。

组合实体模式定义的实体:

组合实体(Composite Entity):它是主要的实体bean。它可以是粗粒度的或者包含一个粗粒度的对象,用于持续生命周期。
粗粒度对象(Coarse-Grained Object):该对象包含依赖对象。它有自己的生命周期,也能管理依赖对象的生命周期。

依赖对象(Dependent Object):依赖对象是一个持续生命周期依赖于粗粒度对象的对象。

策略(Strategies):策略表示如何实现组合实体。
4.数据访问对象模式(Date Access Object Pattern)

数据访问对象模式或DAO模式用于把低级的数据访问API 或操作从高级的业务服务中分离出来。

数据访问对象接口(Data Access Object Interface):该接口定义了在一个模型对象上要执行的标准操作。

数据访问对象实体类(Data Access Object concrete clas):该类实现了上述的接口,负责从数据源中获取数据,数据以源可以是数据库或xml或其他的存储机制。

模型对象/数值对象(Model Object/Value Object):该对象是简单的POJO,包含了get/set方法来存储通过使用DAO类检索到的数据。
5.前端控制器模式(Front Controller Pattern)

前端控制器模式是用来提供一个集中的请求处理机制。所有的请求都由一个单一的处理程序处理。该处理程序可以做认证/授权/记录日志,或跟踪请求,然后把请求传给相应的处理程序。

前端控制器(Front Controller):处理应用程序所有类型请求的单个处理程序,应用程序可以是基于web的应用程序,也可以是基于桌面的应用程序。

调度器(Dispatcher):	前端控制器可能使用一个调度器对象来调度请求到相应的具体处理程序。

视图(View):视图是为请求而创建的对象。
6.拦截过滤器模式(Intercepting Filter Pattern)

拦截过滤器模式:用于对应用程序的请求或响应做一些预处理/后处理。定义过滤器,并把请求传给实际目标应用程序之前应用在请求上。过滤器可以做认证/授权/记录日志,或者跟踪请求,然后把请求传递给相应的处理程序。

过滤器(Filter):过滤器在请求处理程序执行请求之前或之后,执行某些任务。

过滤器链(Filter Chain):过滤器链带有多个过滤器,并在Target上按照定义的顺序执行这些过滤器。

Target:该对象是请求处理程序。

过滤管理器(Filter Manager):过滤管理器管理过滤器和过滤链。

客户端(Client):Client是向Target对象发送请求的对象。
7.服务定位模式(Service Locator Pattern)

服务定位器模式用在我们想使用JNDI查询定位各种服务的时候。考虑到为某个服务查找JNDI的代价很高,服务定位器模式充分利用了缓存技术。在首次请求某个服务时,服务定位器在JNDI中查找服务,并缓存该服务对象。当再次请求相同服务时,服务定位器会在它的缓存中查找,这样可以在很大程度上提高应用程序的性能。

实现的实体对象:

服务(Service):实际处理请求的服务。对这种服务的引用可以在JNDI服务器中查找到。

Context/初始的Context:JNDI Context 带有对要查找的服务的引用。

服务定位器(Service Locator):服务定位器是通过JNDI查找和缓存服务来获取服务的单点接触。

缓存(Cache):缓存存储服务的应用,以便复用它们。

客户端(Client):Client是通过ServiceLocator调用服务的对象。
8.传输对象模式(Transfer Object Pattern)

传输对象模式用于从客户端向服务器一次传输带有多个属性的数据。传输对象也称作数值对象。传输对象是一个具有getter/setter方法的简单POJO类,它是可序列化的,所以它可以通过网络传输。

它没有任何的行为:

服务器端的业务类通常从数据库读取数据,然后填充POJO,并把它发送到客户端或按值传递它。

对于客户端,传输对象是只读的:

客户端可以创建自己的传输对象,并把它传递给服务器,一遍一次性更新数据库中的数值。

关于传输对象模式的实体:

业务对象(Business Object):为传输对手填充数据的业务服务。
传输对象(Transfer Object):简单的POJO,只有设置/获取属性的方法
客户端(Client):客户端可以发送请求或者发送传输对象到业务对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值