设计模式简记
1.
(静态工厂模式)
简单工厂模式-----根据给工厂XXFactory传入"产品"类型参数,XXFactory工厂会调用静态方法"制造相应的产品"出来
组成:
a.工厂角色-------工厂中有静态方法负责根据"用户"的请求动态的创建相应的产品,即实例化有大量共同接口的类
(注意:Factory工厂不是什么产品都生产,而是一个Factory只针对一类有共同特征的产品)
b.抽象产品角色--抽象出一类产品的共同特征的接口/抽象类,被具体产品继承,且在工厂中使用抽象产品接口/抽象类
来接收生产出来的具体产品对象(子类对象都可被父类类型的变量接收),并返回
c.具体产品角色---继承抽象产品接口/抽象类, 工厂中真正创建(new)出来的是具体产品
例:
工厂角色--------Factory类
a.有一抽象产品类型的属性Operator,用于接收创建出来的具体操作符对象
b.有一静态createOperate(String)方法,可根据参数(如+-)创建具体操作符对象赋给Operator属
性并返回
抽象产品角色---Operator抽象类
a.两个操作数属性,用于进行操作
b.operate方法,未被实现,(实现即是具体操作符对两个操作数的具体操作过程,如+-*/),返回类型
具体产品角色---AddOper类/SbuOper类----继承Operator抽象类,并实现operate方法中各自的具体操作(+/-)
使用:此时若有两个操作数进行相加,
1.使用Factory类的静态方法createOperate("+")----输入"+"参数请求创建AddOper加操作符对象
并自己定义抽象类类型的变量进行接收Operator operator = createOperate("+")
2.给operator对象的两个操作数赋值,operator.num1=XX/operator.num2=XX
3.调用operator的操作方法double result = operator.operate(),便会进行相加操作并返回
?
缺点:
a.违反OCP------开放-关闭原则,当要加入新产品时,需要修改Factory工厂类,把创建新产品的代码给加上,不能直接扩展
b.Factory内部集中了所有实例的创建逻辑,即根据不同条件创建不同的实例,这样当实例较多时,该逻辑也会比较混乱
违反高内聚责任分配原则,因此简单工厂非常适合于简单结构的情况下
总结:
简单工厂模式的优点是将对象的创建统一管理起来,将对象创建细节屏蔽(对客户端)起来,如果产品类发生了变化,无需修改提供给客户端的接口,达到了解耦合;缺点是,如果存在多个产品结构的时候,使用同一个工厂来管理,只要某一个产品结构发生变化,或者新增一个产品结构,都需要去修改工厂类的实现,也就是说,产品结构与工厂是高耦合的。
?
2.
strategy(策略模式)----用于封装策略/算法的(更完美的操纵多个有相同规则的算法)
1)context类-用于统一的控制各算法的具体实现类,通过构造函数传参可构造出各算法的具体实现类,用算法的抽象类来接收
--(也可结合简单工厂模式,将选择构造哪个具体实现算法类的操作放入context中)
--有一getResult方法,其中调用"抽象类接收到的" "算法的具体实现类"的算法,context完全把具体实现类封装了
2)算法的抽象类------抽象出各算法的共同特性,或定义各具体算法的共用接口(方法)
3)算法的具体实现类--实现抽象类中的算法接口/方法
---这样,使用时,只需要context类,即可操作各具体算法
---总体过程:
1.生成XXContext类对象,且给其构造函数传入要生成的具体算法对象,或传入具体算法的标志(字符串等),结合工厂模式自动生成相应的算法类
2.XXContext接收后,创建 具体算法对象,或根据相应算法的标志创建相应的算法对象,并保存到XXContext的算法抽象类类型(可接收任何具体算法对象)的属性中
3.现在XXContext中已经保存了,我们需要使用的 "具体算法对象",我们可以调用XXContext类中的getResult方法,使用算法进行计算
(注:getResult方法中调用 "XXContext中保存的抽象类对象"的"抽象方法"----即可实现对所有的具体实现算法的计算操作)
3.
单一职责模式----(准确解释)就一个类而言,应该仅有一个引起它变化的原因
(比如界面和业务逻辑-----若界面和业务逻辑都在同一类内,则更改界面和更改业务逻辑都会引起该类的变化....职责单一)
4.
开放-封闭原则或开闭原则(OCP-The Open-Closed Principle)------尽可能的不对代码修改但可以扩展的思想
------------(面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码)
5.
依赖倒转原则-------针对接口编程,不要对实现编程(如内存条是针对接口编程的,若是针对实现来设计,内存就要对应到具体的某个品牌的主板上,这样内存将会和品牌一一挂勾,没有现在的这种通用性了)
接口的理解---------接口就如同插座一样,负责接收各种各样的插头,只要插头符合插座的接口,就可以使用
!!!在软件中,如同在一个类A中,使用一个"接口类型的变量I"去接收一个"实现了接口的类B的对象",只要这个类B是实现的接口I,并且按照这个接口I的规则去编程,则实现该接口I的类B或其他的类C,D....等都可以插入到"类A的接口变量(插座)"中去,这就是面向接口编程
(这样不用管类A是怎么实现的,只需要知道他需要的接口I是什么样的,我们面向这个接口I去编程,到时候把自己制作的插头插到类A中的插座上,就可以和类A进行扩展/结合)
6.composite模式---
问题--->Component接口所定义的方法中,有一些方法是只对Composite子类有意义,比如操作子结点的方法,而这些方法
对Leaf子类没有意义的.
解决--->[截选自GOF设计模式]
例如,访问子节点的接口是Composite类的一个基本组成部分,但对Leaf类来说并不必要。但是如果我们把一个
Leaf看成一个没有子节点的Component, 就可以为在Component类中定义一个缺省的操作,用于对子节点进行
访问,这个缺省的操作不返回任何一个子节点。Leaf 类可以使用缺省的实现,而Composite类则会重新实现这个
操作以返回它们的子类。
7.
Decorator和Proxy模式区别:[摘自???]
英文的东西比较简单:直接从英文原意理解就最正确了
proxy:the agency, function, or office of a deputy who acts as a substitute for another
即proxy是一个替代品,他替代了原有的东西(当然也可以在经过适当处理后,再把请求发送给原物品,当然也可以做完全不同的事),proxy与原物品是不同的,proxy是主要的主动体,原物品最多是次要的被动体。
decorator: furnish with something ornamental
decorator不改变原物品的特性,但增加了一些装饰性的东西,decorator与原物品本质是相同的,原物品是主要的,decorator最多是些次要的装饰。
8.
Decorator可以看作是对象的一个外壳,而Strategy模式可以看作是对象的内核。因此:
Decorator模式更适合改变对象的外壳,而Strategy模式更适合改变对象的内核。
9.
Facade模式:[截选自GOF设计模式]一个子系统与一个类的相似之处是,它们都有接口并且它们都封装了一些东西—类封装了状态和操作,而子系统封装了一些类。考虑一个类的公共和私有接口是有益的,我们也可以考虑子系统的公共和私有接口。
个人理解:类可以对外提供一些接口,同时类内部有一些私有接口供自己使用,也有一些接口即可供外部使用也可供自己使用,对于大多数用户,可能经常只需要使用类的部分公共对外的接口,而对于一些私有接口甚至是一部分公共对外的接口几乎没有使用的需求。类似于一个子系统中有一些类,一些是提供给系统外的客户使用,一些是供系统内部使用,还有一部分即供系统外部使用也供系统内部使用,而对于一般的客户而言,可能经常只需要使用子系统中的一部分类,这时可使用Facade模式将子系统抽象化、简单化,提供给客户简单一致的接口,隐藏系统内部客户不需要使用的类,这些类只在门面内部使用而不提供给客户,这样便可使这些简单的用户更易于操作子系统,而对于高级用户完全可以越过Facade门面,去使用子系统内部的其他类。
?