设计模式应用有感总结

设计模式应用有感总结

1、桥接设计模式

(1)从形式上看,就是将一个抽象(接口)作为成员变量放入另一个抽象类中,以实现【抽象与实现的解耦】,这样与可以各自做自己的事情而互不影响,可以独立变化,而又自由组合。有点类似对象的链接。接口实现对象一般都是通过抽象类继承类构造函数参数传进去,构造函数参数决定桥接的是哪个实现接口的对象,然后由实现接口的对象执行任务。

2、代理设计模式

(1)代理类可以对委托类进行功能扩展,所以当需要对某个类功能(操作或方法)进行扩展时可以使用代理模式

3、享元模式

基本介绍

(1)享元模式,又称蝇量模式:

(2)运用共享技术实现大量细粒度对象的复用

应用

(1)享元模式是池技术的重要实现方式

(2)池技术:String 常量池、数据库连接池、缓冲池

(3)常用于系统底层开发,解决系统的性能问题:如数据库连接池,池中是创建好的连接对象,若池中有符合需求的对象时直接用,避免重新创建;若池中没有符合需求的,则创建一个

要求

(1)细粒度、共享对象

(2)将对象的信息分为两个部分

  (1)内部状态:指对象共享出来的信息,存储在享元对象内部且不会随环境的改变而改变的状态

  (2)外部状态:指对象得以依赖的一个标记,是随环境改变而改变的、不可共享的状态

角色

(1)FlyWeight:抽象的享元角色,产品的抽象类,定义了对象的外部状态和内部状态的接口或实现

(2)ConcreteFlyWeight:具体的享元角色,产品的实现类,实现了抽象角色定义的相关业务

(3)UnSharedConcreteFlyWeight:不可共享的角色,一般不会出现在享元工厂中

(4)FlyWeightFactory:享元工厂类,内部提供一个池容器,储存ConcreteFlyWeight,同时提供从池中存取数据的操作

事项

(1)享:共享,元:对象

(2)应用场景:系统中有大量对象,这些对象消耗大量内存,并且对象的状态大部分可以外部化时

(3)一般用 HashMap / HashTable 存储 ConcreteFlyWeight,key作为唯一标识码判断 ConcreteFlyWeight

(4)优点

(1)解决重复对象的内存浪费的问题,减少了对象的创建,降低了程序内存的占用,提高效率

(2)提高了系统的复杂度,需要分离出内部状态和外部状态

(5)缺点

  (1)提高了系统的复杂度,需要分离出内部状态和外部状态。而外部状态具有固化特性,不应该随着内部状态的改变而改变

  (2)享元模式需要额外维护对象缓存池。

(6)例子

春运买火车票是一件疯狂的事情,同一时刻会有大量的查票请求涌向服务器,服务器必须做出应答来满足我们的购票需求。试想,这些请求包含着大量的重复,比如从A地到B地的车票情况,如果每次都重复创建一个车票查询结果的对象,那么GC任务将非常繁重,影响性能,这就用到了我们的享元模式。当然也会有不重复的请求,比如我想购买从A地到B地的高铁票,而你想买从A地到B地的动车票。

4、命令模式

定义:命令是对命令的封装,每一个命令都是一个操作,请求方发出请求,接收方接收请求,并执行操作。命令模式解耦了请求方和接收方,命令模式属于行为型模式

命令模式中的4个角色:

(1)接收者角色(Receiver):负责具体执行一个请求(真正执行命令的对象)

(2)命令角色(ICommand):定义需要执行的所有命令行为

(3)具体的命令角色(ConcreteCommand):内部维护一个Receiver

(4)请求者角色(Invoker):接收客户端的命令,并执行命令

例如:客户端把命令给Invoker.setCommand,然后Invoker执行命令Invoker.execute

例子 :遥控操作电视

5、责任链模式

责任链模式的优点如下:

(1)降低了对象之间的耦合度
发送者无需知道最终由哪一个handler处理其请求,也无需知道请求的传递过程
handler无需知道是哪一个发送者发送的请求,就像奖学金评选系统一样,本科生、研究生和博士生都可能是申请者
(3)增强了系统的可扩展性
    如果新增handler无需修改请求者的代码逻辑,满足开闭原则

(4)增强了给对象指派职责的灵活性 
随着工作流程的变化,可以动态地改变链内的handler、可以动态地调整handler的次序,还可以动态地增加或删除handler
(5)简化了对象之间的连接
每个对象只需保持一个指向其后继者的next引用,不需保持其他所有处理者的引用,避免了使用众多的 if···else 语句。
(6)责任分担
每个handler只需要处理自己分内的工作,分外的工作可以传递给下一个handler去完成
这样的话,每个handler的分工明确,符合类的单一职责原则
自己对增强了给对象指派职责的灵活性的理解

以请假审批为例,使用list记录责任链
可以通过set操作,将组长换成方向负责人
可以通过swap操作,调整部长和总监的审批顺序(不太恰当的例子??)
可以通过add(index, element)操作,在指定位置增加handler
可以通过remove操作删除handler
 

责任链模式具有如下缺点:

(1)不能保证每个请求一定被处理:传入责任链的请求,可能直到链的末尾都没有对应的handler可以处理它
(2)对比较长的责任链,请求的处理可能涉及多个handler,系统性能将受到一定影响。
(3)责任链建立的合理性由客户端保证,增加了客户端的复杂性
(4)可能会由于责任链的错误设置而导致系统出错,如循环调用
(5)自己的疑惑: 为什么要由客户端创建责任链,权利下放很可能会出大问题的r>  

6、适配器模式

  • 源(Adapee)角色:现在需要适配的接口。(比如:猫)
  • 目标(Target)角色:这就是所期待得到的接口(类适配器模式,目标不可以是类)(一般是接口)
  • 适配器(Adapter)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不可以是接口,而必须是具体类。

7、观察者模式

 观察者模式,也被称为发布订阅模式,是一种行为型设计模式,也是在实际的开发中用得比较多的一种模式,当对象间存在一对多关系时,就可以使用观察者模式。定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象(观察者对象)都得到通知并被自动更新。

如何实现的r> 观察者模式首先有一个被观察类,这个类中有一个 ArrayList 存放观察者们。除此以外还应有类状态和设置和获取状态的方法,状态改变时通知所有观察者,观察者类可以有个抽象类,所有的观察者类继承这个抽象类,观察者类有它要观察的对象。

举例实现
观察者模式使用两个类 Subject、Observer 。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。
ObserverPatternDemo,我们的演示类使用 Subject 和实体类对象来演示观察者模式。

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

如何解决:使用面向对象技术,可以将这种依赖关系弱化。

关键代码:在抽象类里有一个 ArrayList 存放观察者们。

应用实例: 1、拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。 2、西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。

优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。

缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景:

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

注意事项: 1、JAVA 中已经有了对观察者模式的支持类。 2、避免循环引用。 3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

8、修饰模式

定义

修饰模式:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。

修饰模式主要创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂。

使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。

注意事项:可代替继承。

9、门面模式

门面模式
门面模式(Facade Pattern)又叫外观模式,提供了一个统一的接口,提供了一个统一的接口,用来访问子系统中的一群接口。其主要特征是定义了一个高层接口,让子系统更容易使用,属于结构性模式。
其实,在我们日常的编码过程中,我们都在有意无意地大量使用门面模式,但凡只要高层模块需要调度多个子系统(2个以上类对象),我们都会自觉地创建一个新类封装这些子系统,提供精密接口,让高层模块可以更加容易简介调用这些子系统的功能。尤其是现阶段各种第三方SDK,各种块原类库,很大概率都会使用门面模式。尤其是你觉得调用越方便的,门面模式适用的一般更多。

门面模式的应用场景
1、子系统越来越复杂,增加门面模式提供接口
2、构建多层系统结构,利用门面对象作为每层的入口,简化层间调用

门面模式的通用写法
门面模式主要包含2种角色:
外观角色(Facade):也称门面角色,系统对外的统一接口;
子系统角色(SubSystem):可以同时有一个或多个SubSystem。每个SubSytem都不是一个单独的类,而是一个类的集合。SubSystem并不知道Facade的存在,对于SubSystem而言,Facade只是另一个客户端而已(即Facade对SubSystem透明)。
下面是门面模式的通用代码,首先分别创建3个子系统的业务逻辑SubSystemA、SubSystemB、SubSystemC,代码很简单:
门面模式业务场景实例
比如信誉卡积分兑换礼品的商城,这礼品商城中的大部分功能并不是全部重新开发的,而是要去对接已有的各个子系统,这些子系统可能涉及到积分系统、支付系统、物流系统的接口调用/如果所有的接口调用全部由前端发送 络请求去调用现有的接口的话,一则会增加前端开发人员的难度,二则会增加一些 络请求影响页面的性能。这个时候就可以发挥门面模式的优势了。将所有现成的接口全部整合到一个类中,由后端提供统一的接口给前端调用,这样前端开发人员就不需要关心各接口的业务关系,只需要把精力集中在页面交互上。下面我们用代码模拟下这个场景。
门面模式的优缺点
优点:
1、简化了调用过程,无需深入了解子系统,以防给子系统带来风险。
2、减少系统依赖、松散耦合
3、更好地划分访问层次,提高了安全性
4、遵循迪米特法则,即最少知道原则
缺点:
1、当增加子系统和扩展系统行为时,可能容易带来未知风险
2、不符合开闭原则
3、某些情况下可能违背单一职责原则
 

10、组合模式

组合模式中的角色:

Component抽象组件:为组合中所有对象提供一个接口,不管是叶子对象还是组合对象。
Composite组合节点对象:实现了Component的所有操作,并且持有子节点对象。
Leaf叶节点对象:叶节点对象没有任何子节点,实现了Component中的某些操作。
组合模式让我们能用树形方式创建对象的结构,树里面包含了组合以及个别的对象。

使用组合结构,我们能把相同的操作应用在组合和个别对象上。换句活说,在大多数情况下,我们可以忽略对象组合和个别对象之问的差别。

11、备忘录模式

备忘录模式又称快照模式,或者令牌模式。是指在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态,属于行为型模式。

发起人角色(Originator):负责创建一个备忘录,记录自身需要保存的状态,具备状态回滚功能
备忘录角色(Memento):用于存储Originator的内部状态,可以防止Originator以外的对象访问
备忘录管理员角色(Caretaker):负责存储。提供管理员备忘录,无法对备忘录内容进行操作和访问
 

12、中介模式

1. 核心思想
由中介来承接房客与房东之间的交互过程,可以使得整个租房过程更加畅通、高效。这在程序中叫作中介模式,中介模式又称为调停模式。

在很多系统中,多个类很容易相互耦合,形成 状结构。中介模式的作用就是将这种 状结构分离成星型结构。经过这样的调整后,对象之间的结构更加简洁,交互更加顺畅。

2. 设计要点
中介模式主要有以下三个角色,在设计中介模式时要找到并区分这些角色:

交互对象(InteractiveObject):要进行交互的一系列对象。
中介者(Mediator):负责协调各个对象之间的交互。
具体中介者(Mediator):中介的具体实现。
3. 优缺点
优点

Mediator将原本分布于多个对象间的行为集中在一起,作为一个独立的概念并将其封装在一个对象中,简化了对象之间的交互。
将多个调用者与多个实现者之间多对多的交互关系,转换为一对多的交互关系,一对多的交互关系更易于理解、维护和扩展,大大减少了多个对象之间相互交叉引用的情况。
缺点

中介者承接了所有的交互逻辑,交互的复杂度转变成了中介者的复杂度,中介者类会变得越来越庞大和复杂,以至于难以维护。
中介者出问题会导致多个使用者同时出问题。
4. 应用场景
一组对象以定义良好但复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
想通过一个中间类来封装多个类中的行为,同时又不想生成太多的子类。
13、状态模式

1.模式动机

改变对象状态同时执行某个动作

  • 在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的(stateful)对象,这样的对象状态是从事先定义好的一系列值中取出的。当一个这样的对象与外部事件产生互动时,其内部状态就会改变,从而使得系统的行为也随之发生变化。
  • 在UML中可以使用状态图来描述对象状态的变化。

2.模式定义

状态模式(State Pattern) :允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。其别名为状态对象(Objects for States),状态模式是一种对象行为型模式。

3.模式结构

状态模式包含如下角色:

  • Context: 环境类
  • State: 抽象状态类
  • ConcreteState: 具体状态类

14、策略模式

本质:分离算法,选择实现。

策略模式:针对一组算法,将每一个算法封装到具有共同接口的独立的类中,使得它们可以互换。

使用策略模式可以把行为和环境分割开来。环境类Context负责查询要做什么,各种算法则在具体策略类(ConcreteStrategy)中提供。

当出现新的促销折扣或现有的折扣政策出现变化时,只需要实现新的策略类,并在客户端登记即可。

环境(Context):有一个Strategy类的引用,和具体的策略类交互。
抽象策略(Strategy)角色:一个接口或抽象类,给出规范。
具体策略(ConcreteStrategy)角色:具体算法或行为。

上下文使用具体策略对象,具体策略对象也可以从上下文获取所需要的数据,因此,可以将上下文当做参数传递给具体策略对象。

上下文封装着具体策略对象需要的数据,具体策略对象通过回调上下文的方法来获取这些数据。
 

策略模式的特点
功能:具体算法从具体业务处理中独立
多个if-else出现考虑使用策略模式
策略算法是形同行为的不同实现(多态)
客户端选择,上下文来具体实现策略算法

使用场景
同一个算法,有很多不同的实现情况。

一个定义了很多行为的类,通过多个if-else语句来选择这些行为的情况

优缺点
优点:

避免让客户端涉及到重要算法和数据
避免使用难以维护的多重条件选择语句
易扩展
缺点:

判断逻辑在客户端,需求改变时,要更改客户端的程序。
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。
增加了对象的数目
只适合扁平的算法结构

15、责任链模式

责任链模式主要应用在系统中的某些功能需要多个对象参与才能完成的场景。

16、访问者模式

访问者模式的定义:

访问者模式是封装一些施加于某种数据结构之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变。访问者模式适用于数据结构相对稳定的系统, 它把数据结构和作用于数据结构之上的操作之间的耦合度降低,使得操作集合可以相对自由地改变。

 数据结构的每一个节点都可以接受一个访问者的调用,此节点向访问者对象传入节点对象,而访问者对象则反过来执行节点对象的操作。这样的过程叫做“双重分派”。节点调用访问者,将它自己传入,访问者则将某算法针对此节点执行。

这里需要明确一点:访问者模式中具体访问者的数目和具体节点的数目没有任何关系。从访问者的结构图可以看出,访问者模式涉及以下几类角色。

抽象访问者角色(Vistor):声明一个活多个访问操作,使得所有具体访问者必须实现的接口。

具体访问者角色(ConcreteVistor):实现抽象访问者角色中所有声明的接口。

抽象节点角色(Element):声明一个接受操作,接受一个访问者对象作为参数。

具体节点角色(ConcreteElement):实现抽象元素所规定的接受操作。

结构对象角色(ObjectStructure):节点的容器,可以包含多个不同类或接口的容器。

访问者模式的应用场景:

 每个设计模式都有其应当使用的情况,那让我们看看访问者模式具体应用场景。如果遇到以下场景,此时我们可以考虑使用访问者模式。

1、如果系统有比较稳定的数据结构,而又有易于变化的算法时,此时可以考虑使用访问者模式。因为访问者模式使得算法操作的添加比较容易。

2、如果一组类中,存在着相似的操作,为了避免出现大量重复的代码,可以考虑把重复的操作封装到访问者中。(当然也可以考虑使用抽象类了)

3、如果一个对象存在着一些与本身对象不相干,或关系比较弱的操作时,为了避免操作污染这个对象,则可以考虑把这些操作封装到访问者对象中。

访问者模式的优缺点 :

访问者模式具有以下优点:

1、访问者模式使得添加新的操作变得容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,添加新的操作会变得很复杂。而使用访问者模式,增加新的操作就意味着添加一个新的访问者类。因此,使得添加新的操作变得容易。
2、访问者模式使得有关的行为操作集中到一个访问者对象中,而不是分散到一个个的元素类中。这点类似与”中介者模式”。
3、访问者模式可以访问属于不同的等级结构的成员对象,而迭代只能访问属于同一个等级结构的成员对象。
 访问者模式也有如下的缺点:

1、增加新的元素类变得困难。每增加一个新的元素意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中添加相应的具体操作。

总结:

 访问者模式是用来封装一些施加于某种数据结构之上的操作。它使得可以在不改变元素本身的前提下增加作用于这些元素的新操作,访问者模式的目的是把操作从数据结构中分离出来。

17、前端控制器模式

前端控制器模式(Front Controller Pattern)是用来提供一个集中的请求处理机制,所有的请求都将由一个单一的处理程序处理。该处理程序可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相应的处理程序。以下是这种设计模式的实体。

 (1)前端控制器(Front Controller) – 处理应用程序所有类型请求的单个处理程序,应用程序可以是基于 web 的应用程序,也可以是基于桌面的应用程序。
(2)调度器(Dispatcher) – 前端控制器可能使用一个调度器对象来调度请求到相应的具体处理程序。
(3)视图(View) – 视图是为请求而创建的对象。

18、服务定位器模式

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

  • 服务(Service) – 实际处理请求的服务。对这种服务的引用可以在 JNDI 服务器中查找到。
  • Context / 初始的 Context – JNDI Context 带有对要查找的服务的引用。
  • 服务定位器(Service Locator) – 服务定位器是通过 JNDI 查找和缓存服务来获取服务的单点接触。
  • 缓存(Cache) – 缓存存储服务的引用,以便复用它们。
  • 客户端(Client) – Client 是通过 ServiceLocator 调用服务的对象。

使用场景:当服务比较多且服务要被多次请求时,可以使用服务定位器模式

19、组合实体模式

组合实体模式(Composite Entity Pattern)用在 EJB 持久化机制中。一个组合实体是一个 EJB 实体 bean,代表了对象的图解。当更新一个组合实体时,内部依赖对象 beans 会自动更新,因为它们是由 EJB 实体 bean 管理的。以下是组合实体 bean 的参与者。

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

20、业务对象(BO)和传输对象(VO:也叫数值对象)都代表了实体。 

(1)BO获取实体函数返回结果类型用VO类型

(2)BO更新实体过程参数类型用VO类型

(3)VO更新获取属性参数、返回类型和属性类型一致(Get/Set)

21、数据访问对象模式

数据访问对象模式(Data Access Object Pattern)或 DAO 模式用于把低级的数据访问 API 或操作从高级的业务服务中分离出来。以下是数据访问对象模式的参与者。

  • 数据访问对象接口(Data Access Object Interface) – 该接口定义了在一个模型对象上要执行的标准操作。
  • 数据访问对象实体类(Data Access Object concrete class) – 该类实现了上述的接口。该类负责从数据源获取数据,数据源可以是数据库,也可以是 xml,或者是其他的存储机制。
  • 模型对象/数值对象(Model Object/Value Object) – 该对象是简单的 POJO,包含了 get/set 方法来存储通过使用 DAO 类检索到的数据。

22、拦截过滤器模式

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

  • 过滤器(Filter) – 过滤器在请求处理程序执行请求之前或之后,执行某些任务。
  • 过滤器链(Filter Chain) – 过滤器链带有多个过滤器,并在 Target 上按照定义的顺序执行这些过滤器。
  • Target – Target 对象是请求处理程序。(真正处理程序)
  • 过滤管理器(Filter Manager) – 过滤管理器管理过滤器和过滤器链。
  • 客户端(Client) – Client 是向 Target 对象发送请求的对象。

23、MVVM简介

view是视图层 也就是用户界面 前段主要由html和css来构成 为了方便地展现ViewModel或者Model层的数据

Model是指数据模型 泛指后端进行的各种业务逻辑处理和数据操控 主要围绕数据层系统展开 这里的难点主要在于需要和前段约定统一的接口规则

ViewModel由前段开发人员组织生成和维护的视图数据层 在这一层 前段开发者从后端获取取得到Model数据层进行转换出来 做第二封装 以生成符合View层使用预期的视图数据模型 视图状态和行为都封装在ViewModel里 这样的封装使得ViewModel可以完整第去描述View层

什么是MVVM

MVVM(Model-ViewModel)是一种软件架构设计模式,它是一种简化用户界面的事件驱动编程方式

在MVVM架构中 是不允许数据和视图直接通信的 只能通过ViewModel来通信 而ViewModel就是定义了一个Observer观察者 ViewModel是链接View和Model的中间件

ViewModel能够观察到数据的变化并对视图对应的内容进行更新

ViewModel能够监听视图的变化 并能够通知数据发生变化

到此 我们就明白了, VUE.js就是一个MVVM的实现者 它的核心就是实现了DOM监听与数据绑定
MVVM源自于经典的MVC(Model-view-Controller)模式MVVM的核心是ViewModel层 负责转换Model中数据对象来让数据变得更容易管理和使用其作用如下 :
该层向上与视图层进行双向数据绑定
向下与Model层通过接口请求进行数据交互

三 为什么要使用MVVM

低耦合:视图(view)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的View上,当View变化 的时候Model可以不变 当Model变化的时候 View也可以不变

可复用:可以 把一些三视图逻辑放到一个ViewModel里面 让很多View重用这段 视图逻辑

独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel) 设计人员可以专注页面设计

可测试:界面素来是比较难于测试的,而是在侧试可以针对ViewModel来写

MVVM的组成部分

View(HTML, CSS, Templater)
双向数据绑定
ViewModel(JavaScript,Runtime,Compiler)
AJAX jSON
Model
JAXA业务逻辑器
数据库

MvvM 与 MVP 非常相似,唯一的区别是 View 和 Model 进行双向绑定( data 一 binding ) ,两者之间有一方发生变化则会反应到另一方上。而 MVP 与 MVVM 的主要区别则是, MVP 中的 View 更新需要通过 Presenter ,而 MVVM 则不需要,因为 View 与 Model 进行了双向绑定,数据的修改会直接反应到 View 角色上,而view 的修改也会导致数据的变更。此时, ViewModel 角色需要做的只是业务逻辑的处理,以及修改 view 或者 Model 的状态。 MVVM 模式有点像 ListView 与 Adapter 、数据集的关系,这个 Adapter 就是 viewModel 角色,它与 View 进行了绑定,又与数据集进行了绑定,当数据集合发生变化时,调用 Adapter 的 notifyDatasetChanged 之后 View 就直接更新,它们之间没有直接的耦合,使得 ListView 变得更为灵活。

MVP 和MVVM 选型
MVP 改造 不需要引入新的库,而且已经能够满足当前需要。
MVVM 需要引入 databinding 库,有接入成本和学习成本;
后期可以使用Jetpack 组件中 ViewModel 来实现MVVM ,未来可能考虑 切换到MVVM。

MVVM 和 MVI
MVVM 缺陷
MVVM 与 MVP 的主要区别在于双向数据绑定,但由于很多人(比如我)并不喜欢使用 DataBindg,其实并没有使用 MVVM 双向绑定的特性,而是单一数据源
当页面复杂时,需要定义很多 State,并且需要定义可变与不可变两种,状态会以双倍的速度膨胀,模板代码较多且容易遗忘
View 与 ViewModel 通过 ViewModel 暴露的方法交互,比较零乱难以维护。
MVI 优势
而 MVI 可以比较好的解决以上痛点,它主要有以下优势

强调数据单向流动,很容易对状态变化进行跟踪和回溯

使用 ViewState 对 State 集中管理,只需要订阅一个 ViewState 便可获取页面的所有状态,相对 MVVM 减少了不少模板代码

ViewModel 通过 ViewState 与 Action 通信,通过浏览 ViewState 和 Aciton 定义就可以理清 ViewModel 的职责,可以直接拿来作为接口文档使用。
当然 MVI 也有一些缺点,比如

所有的操作最终都会转换成 State,所以当复杂页面的 State 容易膨胀

state 是不变的,因此每当 state 需要更新时都要创建新对象替代老对象,这会带来一定内存开销
24、空对象模式

Null 对象不是检查空值,而是反应一个不做任何动作的关系。

25、迭代器模式

 1、迭代器和聚合对象是分离的

26、建造者模式(Builder Pattern)

使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

主要解决:主要解决在软件系统中,有时候面临着”一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

何时使用:一些基本部件不会变,而其组合经常变化的时候。

如何解决:将变与不变分离开。

关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。

应用实例: 1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的”套餐”。 2、JAVA 中的 StringBuilder。

优点: 1、建造者独立,易扩展。 2、便于控制细节风险。

缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。

使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

27、原型模式

一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

28、适配器模式

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。

意图:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

应用实例: 1、美国电器 110V,中国 220V,就要有一个适配器将 110V 转化为 220V。 2、JAVA JDK 1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,则要将以前系统的 Enumeration 接口转化为 Iterator 接口,这时就需要适配器模式。 3、在 LINUX 上运行 WINDOWS 程序。 4、JAVA 中的 jdbc。

(1)目标接口的适配器类:用于适配各种不同的源接口

(2)目标接口的实体类:引用目标接口的适配器类间接去适配各种不同的源接口 

29、

30、什么是三层

UI(表现层): 主要是指与用户交互的界面。用于接收用户输入的数据和显示处理后用户需要的数据。

BLL:(业务逻辑层): UI层和DAL层之间的桥梁。实现业务逻辑。业务逻辑具体包含:验证、计算、业务规则等等。

DAL:(数据访问层): 与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库。(当然这些操作都是基于UI层的。用户的需求反映给界面(UI),UI反映给BLL,BLL反映给DAL,DAL进行数据的操作,操作后再一一返回,直到将用户所需数据反馈给用户)

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年10月18日
下一篇 2022年10月18日

相关推荐