UML-GoF设计模式
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
UML-GoF设计模式
我认为,本章是重点中的重点。
并⾮23个模式都被⼴泛应⽤,其中常⽤和最为有效的⼤概有15个模式。
1、适配器(Adapter)
1)、使⽤场景
使⽤⼀个已经存在的类,但如果他的接⼝,也就是他的⽅法和你的要求不相同时,考虑使⽤是适配器模式。
就是说,双⽅都不修改⾃⼰的代码的时候,可以采⽤适配器模式。
2)、结构图
3)、相关模式
外观对象:隐藏外部系统的资源适配器也被视为外观对象,因为资源适配器使⽤单⼀对象封装了对⼦系统或系统的访问。
资源适配器:当包装对象时为不同外部接⼝提供适配时,该对象叫资源适配器
4)、准则
类名后缀为“Adapter”。
5)、⽤到的GRASP原则
2、⼯⼚模式
1)、使⽤场景
该模式也常称为“简单⼯⼚”或“具体⼯⼚”。
如:
1)、存在复杂创建逻辑
2)、为提⾼内聚⽽分离创建者职责(关注点分离)
因此,创建称为⼯⼚的纯虚构对象来处理这些创建职责。
2)、结构
⼀般xxxFactory应该是单实例类。
3)、相关模式
通常使⽤单例模式来访问⼯⼚模式。
由谁创建⼯⼚呢?⼀般采⽤单例模式。
3、单例模式
1)、使⽤场景
只有唯⼀实例的类即为“单实例类”。
对象需要全局可见性和单点访问。
因此,建议对类定义静态⽅法⽤以返回单实例。
2)、相关模式
单例模式:通常⽤于创建⼯⼚对象和外观对象
以上整合例⼦:
4、策略模式
1)、使⽤场景
销售的定价策略(也可叫做规则、政策或算法)具有多样性。
在⼀段时间内,对于所有的销售可能会有10%的折扣,后期可能会对超出200元的销售给予10%的折扣,并且还会存在其他⼤量的变化。
因此,在单独的类中分别定义每种策略/规则/政策/算法,并且使其具有共同接⼝。
2 )、结构
策略模式,共同的⽅法内传⼊的参数,通常是上下⽂对象,上图就是sale。
3)、结合⼯⼚模式
1)、使⽤⼯⼚模式创建这些策略类
2)、使⽤单例模式创建⼯⼚类。
5、组合模式
1)、使⽤场景
如果有重叠怎么办?⽐如:
1)⽼年⼈折扣20%
2)购物⾦额满200元享受15%折扣
因此,如何能够处理像原⼦对象⼀样,(多态的)处理⼀组对象或具有组合结构的对象呢?答:定义组合和原⼦对象的类,使他们具有相同的接⼝。
2)、结构
2)、相关模式
通常与策略和命令模式⼀起使⽤。
6、外观模式
1)、使⽤场景
对⼀组完全不同的实现或接⼝(如⼦系统中的实现和接⼝)需要公共、统⼀的接⼝,隐藏掉⼦系统复杂的实现或接⼝。
从⽽使关注点分离。
如:slf4j、通信前置
其与适配器的区别在于,facade模式针对同职能接⼝的抽象并提供公共、统⼀的接⼝,强度的是统⼀。
⽽adapter模式针对的是适配不同接⼝且⽼接⼝不改的场景,强调的是适配。
2)、结构
3)、例⼦
class Program
{
static void Main(string[] args)
{
Facade facade = new Facade();
facade.MethodA();
facade.MethodB();
Console.Read();
}
}
class SubSystemOne
{
public void MethodOne()
{
Console.WriteLine(" ⼦系统⽅法⼀");
}
}
class SubSystemTwo
{
public void MethodTwo()
{
Console.WriteLine(" ⼦系统⽅法⼆");
}
}
class SubSystemThree
{
public void MethodThree()
{
Console.WriteLine(" ⼦系统⽅法三");
}
}
class SubSystemFour
{
public void MethodFour()
{
Console.WriteLine(" ⼦系统⽅法四");
}
}
class Facade
{
SubSystemOne one;
SubSystemTwo two;
SubSystemThree three;
SubSystemFour four;
public Facade()
{
one = new SubSystemOne();
two = new SubSystemTwo();
three = new SubSystemThree();
four = new SubSystemFour();
}
public void MethodA()
{
Console.WriteLine("\n⽅法组A() ---- ");
one.MethodOne();
two.MethodTwo();
four.MethodFour();
}
public void MethodB()
{
Console.WriteLine("\n⽅法组B() ---- ");
two.MethodTwo();
three.MethodThree();
}
}
View Code
4)、相关模式
外观模式通常通过单例模式访问。
7、观察者模式(Observer)
1)、定义
观察者模式⼜叫“发布-订阅(Publish/Subscribe)”模式、⼜叫“委派事件模型”。
之所以被称为观察者模式,是因为监听器或订阅者在对相应事件进⾏观察。
之所以被称为委派事件模型,是因为发布者将事件处理委派给了监听器(订阅者)
2)、使⽤场景
例⼦:⽀付成功后,
1)记录⽇志
2)写数据库
3)前端展⽰⽀付结果
传统⽅式,将以上3个关注点耦合在⼀起写。
随着业务需求越来越多,导致很难维护。
总结:当⼀个对象的改变需要同时改变其他对象时,⽽且还不知道有多少对象有待改变时,应该考虑使⽤观察者模式。
3)、结构
4)、例⼦
public abstract class Subject {
private List<Observer> observers = new ArrayList<Observer>();
//增加观察者
public void attach(Observer observer) {
observers.add(observer);
}
//移除观察者
public void detach(Observer observer) {
observers.remove(observer);
}
//通知
public void notify1() {
observers.forEach(o->o.update());
}
}
public abstract class Observer {
public abstract void update();
}
public class ConcreteSubject extends Subject {
private String subjectState;
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
}
}
public class ConcreteObserver extends Observer {
private String name;
private String observerState;
private ConcreteSubject subject;
public ConcreteObserver( ConcreteSubject subject,String name) {
this.subject = subject;
= name;
}
@Override
public void update() {
observerState = subject.getSubjectState();
System.out.println("观察者"+name+"的新状态是"+observerState); }
public ConcreteSubject getSubject() {
return subject;
}
public void setSubject(ConcreteSubject subject) {
this.subject = subject;
}
}
public class Main {
public static void main(String[] args) {
ConcreteSubject s = new ConcreteSubject();
s.attach(new ConcreteObserver(s, "X"));
s.attach(new ConcreteObserver(s, "Y"));
s.attach(new ConcreteObserver(s, "Z"));
s.setSubjectState("ABC");
s.notify1();
}
}
--输出
观察者X的新状态是ABC
观察者Y的新状态是ABC
观察者Z的新状态是ABC
View Code
5)、⼩结
A、⼀个事件⽀持多个订阅者
public static void main(String[] args) {
ConcreteSubject s = new ConcreteSubject();
//多个订阅者
s.attach(new ConcreteObserver(s, "X"));
s.attach(new ConcreteObserver(s, "Y"));
s.attach(new ConcreteObserver(s, "Z"));
//⼀个事件
s.setSubjectState("ABC");
s.notify1();
}
B、订阅者可动态添加或删除
public abstract class Subject {
private List<Observer> observers = new ArrayList<Observer>(); //增加观察者
public void attach(Observer observer) {
observers.add(observer);
}
//移除观察者
public void detach(Observer observer) {
observers.remove(observer);
}
//通知
public void notify1() {
observers.forEach(o->o.update());
}
}。