设计模式学习 - GOF 23中常见设计模式

项目地址:unity的设计模式学习项目

从github上面扒拉的一个设计模式的项目,里面包含了23种GOF设计模式和针对游戏开发的另一些设计模式

在这里插入图片描述
每一个设计模式都对应几个小demon,Structure是这个模式的大致框架,还有样例可以提供参考理解

这篇博客是我自己记录的这几天的23种常用设计模式的学习,也是我对他们的理解

行为型模式

这些设计模式主要用来设计多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务
包括以下11个

1命令模式:

命令模式将“请求”封装成对象,两者之间通过命令对象进行沟通
在这里插入图片描述

  • Command:定义命令的接口,声明执行的方法。
  • ConcreteCommand:具体命令,通常包含一个命令的参数和Receive,由receive来完成命令的操作
  • Receive:真正执行命令的对象,要能实现命令所要求的功能
  • Invoke:通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者
    在这里插入图片描述
    这个小demon非常多,足够你来理解了

2责任链模式:

使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止
在这里插入图片描述
就是把所有的处理请求的类练成一条链子,把请求放到链的开始,然后链上的每一个类都去判断一下是不是自己所处理的请求,如果不是就交给下一个来处理

3解释器模式:

给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

没学,书上就一句话概括了,啥都没讲,估计不重要

4迭代器模式:

提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节

你自己类比一下c++中的迭代器,和那玩意应该差不多
感觉这个没什么说的,看一看小demon差不多理解差不多了

5中介模式:

用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互

没有中介模式:
在这里插入图片描述

使用中介模式:
在这里插入图片描述

中介类可以理解为快递的集货中心,所有的快递先送到这里,然后在根据地址送到目的地

6备忘录模式:

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态

unity可以用playerPrefs或者文件存储都行

7观察者模式:

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

举个例子:例如100万个粉丝关注了肖战,那么当肖战的微博更新的时候,就会向着100万个粉丝发送消息动态已经更新
在这里插入图片描述

  • Subject:也叫抽象目标类,一个用于保存观察者对象的聚集类并且含有增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
  • Concrete Subject:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
  • Observer:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
  • Concrete Observer:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。

8状态模式:

当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。

个人理解:假设人物动画有Idle Move Shoot Die四个状态,可以把这四个状态做出四个类,然后具体每一个状态的行为写在类里面,这样当切换状态的时候,切换到另一个类就行了

在这里插入图片描述

  • Context:定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
  • State:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
  • Concrete State:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。

9策略模式:

定义一组算法,将每个算法都封装起来,并且使它们之间可以互换、

感觉和这个和状态模式怎么这么像呢
在这里插入图片描述

  • context:持有一个策略类的引用,可以切换具体的策略,也可以调用策略的具体算法,这个类是方便给外部调用
  • Strategy:策略类接口
  • Concrete Strategy:实现了抽象策略定义的接口,提供具体的算法实现。

10模板方法模式:

定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

就是父类的方法是虚的或者抽象的,子类可以重写他的方法,
我个人的理解就是多态的实现

11访问者模式:

封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

假设游戏中有n个玩家,类1需要这些玩家的所有血量值,类2需要这些玩家的所有攻击值
就可以把 类1 和 类2 做成访问者,每一个访问者只需要实现特定的功能

但是访问者模式的缺陷也很明显,就是当Element新增加子类的时候,访问者也需要增加对应的方法,同时也引起所有的子类也要进行相同的改动

结构大概就是这样子
ObjectStructure是被访问者的集合 Visitor是访问者,Element是被访问者基类
在这里插入图片描述

创建型模式

主要关注怎么生产一个对象包括以下6个设计模式

1简单工厂模式 工厂方法模式 抽象工厂模式

简单工厂模式:
就是一堆产品,只有一个工厂类,当增产品的时候,只要在工厂里新增方法即可:
在这里插入图片描述

工厂方法模式:
每一个产品对应每一个工厂
在这里插入图片描述
抽象工厂模式:
工厂方法模式这生产同一类型的产品,抽象工厂模式一个工厂可以生产多种类型产品,同一类型的不同产品分别有不同工厂生产
反正我目前是理解不来,没有做过这东西,不知道具体该用在哪儿

在这里插入图片描述

2建造者模式:

将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成

和工厂模式也有点类似,但是当一个对象的构造比较复杂的时候采用这个,工厂模式适合对象的构造不复杂的情况

在这里插入图片描述

  • Product:它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
  • Builder:它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回产品的方法 getResult()。
  • Concrete Builder:实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
  • Director:调用哪一个具体建造者

3原型模式:

就是拷贝一个对象分为 浅和深 拷贝,浅拷贝就是含有指针的东西还是指向原来的内存块,就在只拷贝了值,引用还是没变

Unity的GameObject.Instantiate()就是一个原型模式

当然c#也有另外的写法 MemberwiseClone()函数。可以克隆一个对象,但是只是浅拷贝

	public override object Clone()
    {
        return this.MemberwiseClone();
    }

4单列模式:

类不能实例化,保证只有一个单列,方便其他的类调用,但凡做过一点点项目都应该知道这个东西,太常用了

单列模式的写法:

写法1:

sealed class Singleton
{
	private Singleton() { }
    private static Singleton _instance;
    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
                _instance = new Singleton();
            return _instance;
        }
    }
}

常规写法就是这个样子,但是当遇到多线程就会有麻烦,在两个if同时判断的时候有可能同时构造对象,这样就构建了两个对象,不符合规定了就

写法2:

加锁,每一个线程进入的时候都要上锁,可避免上述情况

sealed class Singleton
{
    private Singleton() { }
    private static Singleton _instance = null;
    private static readonly object syncObj = new object();
    public static Singleton Instance
    {
        get
        {
            lock (syncObj)
            {
                if (_instance == null)
                    _instance = new Singleton();                
            }
            return _instance;
        }
    }
}

但是这样还是不够好,因为每一次进入都要加锁,比较耗时,能不能省去这个东西呢

写法3:
在instance为空的时候需要加锁,不为空就不需要加锁

sealed class Singleton
{
    private Singleton() { }
    private static Singleton _instance = null;
    private static readonly object syncObj = new object();
    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (syncObj)
                {
                    if (_instance == null)
                        _instance = new Singleton();
                }
            }
            return _instance;
        }
    }
}

但是这样代码比较复杂容易出错,我们可以用c#的静态构造函数来解决这个问题

写法4:

sealed class Singleton
{
    private Singleton() { }
    private static Singleton _instance = new Singleton();//在静态构造中完成
    public static Singleton Instance
    {
        get
        {
            return _instance;
        }
    }
}

但是还是有缺陷,因为我们静态在编译阶段就已经执行了,而我们的需求是要在使用的时候才实例化这个对象,这样就降低了内存的利用率

写法5:
在单列的类中构造一个内部类,这样只有当调用的时候才能触发其静态构造函数

sealed class Singleton
{
    private Singleton() { }
    public static Singleton Instance
    {
        get
        {
            return Nested._instance;
        }
    }
    class Nested
    {
        internal static readonly Singleton _instance = new Singleton();       
    }
}

结构型模式

将类或对象按某种布局组成更大的结构

1适配器模式:

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

类适配器:
在这里插入图片描述
Adapter分别继承Target和Adaptee两个类,然后我的理解就是作为一个调用的中介者

对象适配器:
在这里插入图片描述
Adapter实现Target接口并使用了Adaptee类,实现接口里面的函数,在函数内部调用Adaptee里面对应的函数就完成了转换

2桥接模式:

将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

个人的理解就是: 解决两个群组之间出现的交叉组合情况,典型的面向接口编程

举个列子帮助你理解一下:
在cf里面,角色可以使用武器,
在这里插入图片描述
如果这样的话,当需求增加一个角色葵和一个武器的时候
在这里插入图片描述
那么可想而知,采用这样的方式写代码,需要改动大量的代码

而采用桥接模式就是这个样子:
在这里插入图片描述
这样玩家只要持有武器的接口,不需要知道使用的是那种武器了,武器的具体攻击逻辑只要在子类实现,角色不需要知道

3组合模式:

将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
也就是组合成这个样子:
在这里插入图片描述
大致类图就是这样:
在这里插入图片描述
可以打开项目的结构看一下:
在这里插入图片描述
在这里插入图片描述
以下是整条树的递归遍历:
在这里插入图片描述

4装饰模式:

指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式

在继承的基础上添加新功能之外,使用装饰模式也可以,而且项目后期维护听说基本上都是靠这样添加功能的

先看以下大致框图
在这里插入图片描述
在具体的装饰类里面,调用原来的具体构件,然后在调用添加的功能,这样就完好的实现了扩展的功能

具体的小demon可以打开这个看一看,可以很好的帮助你来理解:
在这里插入图片描述

5外观模式:

要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。外观模式提供一个高层次的接口,使得子系统更易于使用。

我的理解就是
1 对内部的进行再次封装一层,这样的话内部的代码改变就不会引起外部的改变,只需要改变这个外观类就行了,比较的方便该需求,而且也不需要知道内部的逻辑
2 外部需要依赖很多内部,这样耦合度就很高,用一个中间层外观类可以很好解耦
在这里插入图片描述

6享元模式:

运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。

意思就是相同的对象只要保存一个,下一次在用的时候就不需要重新制造一个了,所谓共享
当然有些部分是可以共享的这就是内部状态,不能共享的叫做外部状态
在这里插入图片描述

  1. FlyWeightFactory:
    • 负责产生和管理FlyWeight组件
    • 内部通常使用容器来存储
    • 当产生的是共享组件就放到容容器里面
  2. Flyweight: 操作接口
  3. ConcreteFlyweight: 共享组件
  4. UnConcreFlyweight: 不可共享组件
    • 定义为单独的组件,不包含任何共享资源

7代理模式:

为其他对象提供一种代理以控制对这个对象的访问。
在这里插入图片描述

RealSubject类和他的代理类同时实现Subject接口,这样客户只需要调用代理类就行

就相当于给老板提供了一个秘书,什么事情传达给秘书来就行,秘书在传达给老板,当然秘书可以进行判断是不是需要告诉老板这个消息

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 设计模式是软件开发常用的一种解决方案,它们是一些经过实践验证的可复用设计思想。设计模式允许开发人员在类和对象的结构上灵活地更改,并提供了一种优雅的解决方案来应对各种软件开发问题。 GOF(Gang of Four)是指Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位软件工程师,他们在《设计模式:可复用面向对象软件的基础》一书总结了23常见设计模式,这本书因此而获得了“设计模式圣经”的称号。 这本书以案例为基础,深入浅出地讲解了每个设计模式的原理和应用场景,并提供了C++实现源码。 其,创建型设计模式包括单例模式、工厂方法模式、抽象工厂模式、建造者模式和原型模式。这些模式都提供了一种方式来创建对象,使得程序在实例化对象时更加灵活和可扩展。 结构型设计模式包括适配器模式、装饰器模式、代理模式、组合模式、享元模式和外观模式。这些模式关注如何通过类和对象的组合来创建更大的结构,并提供了一种优雅的方式来简化系统的复杂性。 行为型设计模式包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式和介者模式。这些模式关注对象之间的通信和交互,它们提供了一种优雅的方式来实现松耦合和可维护的代码。 总之,设计模式是软件开发非常重要的一部分,它们提供了一种通用的解决方案来处理常见的设计问题。通过学习和应用设计模式,开发人员可以提高代码的可复用性、可扩展性和可维护性,并加快开发进度。 ### 回答2: 设计模式是软件开发常用的解决问题的一种思维方式或者说是一种已被证实有效的解决问题的方法。GOF 23设计模式是由四位著名的软件工程师提出并总结出的一套经典的设计模式GOF 23设计模式分别是创建型模式、结构型模式和行为型模式。创建型模式包括简单工厂模式、工厂方法模式、抽象工厂模式、单例模式、建造者模式和原型模式。结构型模式包括适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式和代理模式。行为型模式包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、介者模式和解释器模式。 GOF 23设计模式具有不同的应用场景和优势。通过学习和理解这些设计模式,开发者可以更加灵活地应对各种软件开发的问题。同时,掌握这些设计模式也有助于提高代码的可读性、可维护性和可扩展性。 附带C语言实现源码是一种更加具体的学习和理解设计模式的方法。通过查看实现源码,可以更加直观地看到设计模式在实践的应用。这些源码可以作为学习的参考,帮助开发者更好地理解设计模式的思想和使用方式。 总之,设计模式是软件开发非常重要的一部分,通过学习GOF 23设计模式并理解其应用场景和优势,可以提高软件开发的效率和质量。附带C语言实现源码能够更加具体地帮助开发者理解设计模式的实际应用。 ### 回答3: 设计模式是软件工程常用的一种设计思想或模板,可以用于解决特定的问题和提供可重用的解决方案。GOF(Gang of Four)提出了23设计模式,并在书籍《设计模式:可复用面向对象软件的基础》进行了详细的解析和说明。 这本书详细地介绍了23设计模式,包括创建型模式、结构型模式和行为型模式。通过阅读这本书,读者可以了解每种设计模式的特点、适用场景和实现方法。另外,书还通过示例代码的方式演示了每种设计模式的具体实现,并提供了附带的C语言实现源码。 这本书对于理解设计模式的概念和思想非常有帮助。它不仅提供了23设计模式的名字和简介,还详细解释了每种模式的适用场景和应用案例。读者可以通过学习这些设计模式,了解如何将它们应用于自己的软件开发工作,提高代码的可重用性和可维护性。 书的C语言实现源码是帮助读者理解和实践设计模式的重要资源。通过阅读源码,读者可以更加深入地理解每种设计模式的具体实现细节,并进一步提升自己的编程能力。 总之,通过学习设计模式:可复用面向对象软件的基础》这本书,读者可以全面了解设计模式的概念、分类和实现方法,并通过阅读附带的C语言实现源码来加深对设计模式的理解和应用。这将对提升软件设计和开发的能力和水平非常有帮助。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值