永远的万事屋

锈在一起的三角铁


  • 首页

  • 分类

  • 归档

  • 标签

  • 关于

组合模式

发表于 2020-06-17 | 分类于 技术

分享

找到了一篇文章里面对组合模式的分析挺不错的:https://www.cnblogs.com/chenssy/p/3299719.html。这里我只简单记录下我理解的组合模式。

个人理解

  1. 具有组合关系并不算是使用了组合模式
  2. 透明方式比安全方式更贴合组合模式的原则

必须要具备树形结构才适合用到组合模式。所以,感觉组合模式和递归是分区不开的。

享元模式

发表于 2020-06-16 | 分类于 技术

分享

找到了一篇文章里面对享元模式的分析挺不错的:https://blog.csdn.net/justloveyou_/article/details/55045638。但是这里我想聊一些别的方面,关于我们实际用享元模式的思考。

举例说明

在我实际写业务代码时,发现自己很少去用到享元模式,主要有三方面因素:

  1. 并发编程告诉我们尽量少去共享实例,容易引发并发问题
  2. 实际写代码的过程中也很少遇到需要,因为内存的问题需要去考虑共享实例的情况
  3. 最后抽象出来享元角色,以及区分出内部状态和外部状态也是一个需要仔细考量的过程

反过来想,传统的使用Spring写的三层架构中的Service层,Spring就将我们写的Service初始化成了一个单例实例,而且Spring充当了工厂角色,Service Interface充当了Flyweight角色,ServiceImpl充当了Concrete Flyweight角色,而我们Service 方法的参数其实就是Unsharable Flyweight角色,只不过此场景不是细粒度对象的复用,而是大对象的复用。

外观模式

发表于 2020-06-16 | 分类于 技术

定义与特点

外观(Facade)模式的定义:是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。

外观(Facade)模式是“迪米特法则”的典型应用,它有以下主要优点。

  1. 降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响调用它的客户类。
  2. 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。
  3. 降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响外观对象。

外观(Facade)模式的主要缺点如下。

  1. 不能很好地限制客户使用子系统类。
  2. 增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

模式的结构

外观(Facade)模式包含以下主要角色。

  1. 外观(Facade)角色:为多个子系统对外提供一个共同的接口。
  2. 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。
  3. 客户(Client)角色:通过一个外观角色访问各个子系统的功能。
阅读全文 »

装饰器模式

发表于 2020-06-15 | 分类于 技术

定义与特点

装饰(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

装饰(Decorator)模式的主要优点有:

  • 采用装饰模式扩展对象的功能比采用继承方式更加灵活。
  • 可以设计出多个不同的具体装饰类,创造出多个不同行为的组合。

其主要缺点是:装饰模式增加了许多子类,如果过度使用会使程序变得很复杂。

模式的结构

装饰模式主要包含以下角色。

  1. 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
  2. 具体构件(Concrete Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。
  3. 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
  4. 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
阅读全文 »

桥接模式

发表于 2020-06-12 | 分类于 技术

定义与特点

桥接(Bridge)模式的定义如下:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

桥接(Bridge)模式的优点是:
由于抽象与实现分离,所以扩展能力强;
其实现细节对客户透明。

缺点是:由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,这增加了系统的理解与设计难度。

模式的结构

桥接(Bridge)模式包含以下主要角色。

  1. 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
  2. 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
  3. 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
  4. 具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。
阅读全文 »

结构性模式

发表于 2020-06-11 | 分类于 技术

概述

结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。

由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。

代理模式与适配器模式

代理模式的结构

代理模式的主要角色如下。

  1. 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
  2. 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
  3. 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

适配器模式的结构

适配器模式(Adapter)包含以下主要角色。

  1. 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
  2. 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
  3. 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

对比


通过对比发现这两种模式都有三个角色,只考虑对象适配器的话,写出的代码结构类似如下:

class ObjectAdapter implements Target
{
    private Adaptee adaptee;
    public ObjectAdapter(Adaptee adaptee)
    {
        this.adaptee=adaptee;
    }
    public void request()
    {
        adaptee.specificRequest();
    }
}

都是让Proxy或者Adapter类实现客户端真正调用的接口(Target或者Subject)。我个人理解,适配器和代理模式在使用上没有太大的差别,根本的区别是认知上的处理问题的场景。或者是,代理模式一般是不需要做额外工作的(只有类似加日志这种操作),而适配器模式是需要做适配工作的。

设计模式概述

发表于 2020-06-11 | 分类于 技术

根据目的分类

根据模式是用来完成什么工作来划分,这种方式可分为创建型模式、结构型模式和行为型模式 3 种。

  1. 创建型模式:用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使用分离”。GoF 中提供了单例、原型、工厂方法、抽象工厂、建造者等 5 种创建型模式。
  2. 结构型模式:用于描述如何将类或对象按某种布局组成更大的结构,GoF 中提供了代理、适配器、桥接、装饰、外观、享元、组合等 7 种结构型模式。
  3. 行为型模式:用于描述类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,以及怎样分配职责。GoF 中提供了模板方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器等 11 种行为型模式。

根据业务分类

根据模式是主要用于类上还是主要用于对象上来分,这种方式可分为类模式和对象模式两种。

  1. 类模式:用于处理类与子类之间的关系,这些关系通过继承来建立,是静态的,在编译时刻便确定下来了。GoF中的工厂方法、(类)适配器、模板方法、解释器属于该模式。
  2. 对象模式:用于处理对象之间的关系,这些关系可以通过组合或聚合来实现,在运行时刻是可以变化的,更具动态性。GoF 中除了以上 4 种,其他的都是对象模式。

创建型模式 工厂模式

发表于 2020-06-10 | 分类于 技术

创建型模式

创建型模式的主要关注点是“怎样创建对象?”,关注点分离原则,它的主要特点是“将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成。创建型模式由两个主导思想构成。一是将系统使用的具体类封装起来,二是隐藏这些具体类的实例创建和结合的方式。

创建型模式分为以下几种。

  • 单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。
  • 原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例,java的clone就是原型模式的一种实现。
  • 工厂方法(FactoryMethod)模式:定义一个用于创建产品的接口,由子类决定生产什么产品。
    抽象工厂(AbstractFactory)模式:提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。
  • 建造者(Builder)模式:将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。

以上 5 种创建型模式,除了工厂方法模式属于类创建型模式,其他的全部属于对象创建型模式。

类创建型模式与对象创建型模式

创建型模式又分为对象创建型模式和类创建型模式。对象创建型模式处理对象的创建,类创建型模式处理类的创建。详细地说,对象创建型模式把对象创建的一部分推迟到另一个对象中,而类创建型模式将它对象的创建推迟到子类中。

工厂方法模式

定义与特点

工厂方法(FactoryMethod)模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。

工厂方法模式的主要优点有:

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
  • 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

其缺点是:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度

结构与实现

工厂方法模式的主要角色如下。

  1. 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
  2. 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  3. 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  4. 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

与spring的结合

在spring中我们配置的xml或者使用spring框架写的某个实现了抽象工厂的类,都是工厂方法模式的使用场景。最典型的场景,配置DBResource。

抽象工厂模式

定义与特点

抽象工厂(AbstractFactory)模式的定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

使用抽象工厂模式一般要满足以下条件。

  • 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
  • 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。
可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
当增加一个新的产品族时不需要修改原代码,满足开闭原则。

其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

结构与实现

抽象工厂模式同工厂方法模式一样,也是由抽象工厂、具体工厂、抽象产品和具体产品等 4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。现在我们来分析其基本结构和实现方法。

抽象工厂模式的主要角色如下。

  1. 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
  2. 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
  3. 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  4. 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。

与工厂方法模式的区别

抽象工厂模式适用于创建一组(多种)对象的场景,工厂方法模式使用于创建一种对象的场景,简单来说,工厂方法模式有一个创建对象的方法,抽象工厂模式有多个创建不同对象的方法。

依赖倒置、面向接口、控制反转、依赖注入

发表于 2020-06-09 | 分类于 技术

依赖倒置的定义

依赖倒置原则的原始定义为:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象(High level modules shouldnot depend upon low level modules.Both should depend upon abstractions.Abstractions should not depend upon details. Details should depend upon abstractions)。其核心思想是:要面向接口编程,不要面向实现编程(之前比较疑惑面向接口编程与依赖倒置的关系,这句话算是解惑了)。

傻傻分不清楚之总结

  1. 依赖倒置是面向对象开发领域中的软件设计原则,它倡导上层模块不依赖于底层模块,抽象不依赖细节。
  2. 依赖反转是遵守依赖倒置这个原则而提出来的一种设计模式,它引入了 IoC 容器的概念。
  3. 依赖注入是为了实现依赖反转的一种手段之一。

所以,IOC是DIP的继承,DI是IOC的实现,如下所示:

扩展

7 种设计原则是软件设计模式必须尽量遵循的原则,各种原则要求的侧重点不同。其中,开闭原则是总纲,它告诉我们要对扩展开放,对修改关闭;里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;单一职责原则告诉我们实现类要职责单一;接口隔离原则告诉我们在设计接口的时候要精简单一;迪米特法则告诉我们要降低耦合度;合成复用原则告诉我们要优先使用组合或者聚合关系复用,少用继承关系复用。

系统设计文档模板

发表于 2020-06-08 | 分类于 技术

声明

此文章不是我写的,是来自于我之前的团队的,主要是我们当时的leader@闫华做的,微信搜索codeasy可以关注他的公众号。个人觉得此模板还是很不错的,按照这个模板既可以锻炼大家写设计的能力,又能让大家对自己的系统产生一定的思考,所以想要给大家分享出来。因为是维护在内网,要不然我只需要分享一个链接就好了。。。以下是内容:

背景简介

此部分必须要有。
回答以下内容:

  • 这个系统是关于什么的,职责是什么
  • 给谁使用

但不限于以上这些内容。这部分非常重要但要高度凝练,要简洁。目的是提供必要的背景知识,以便读者理解下面章节的内容。

这部分可以与产品经理一起,紧密协作编写。

领域模型

此部分必须要有。

领域模型是对业务的一个抽象建模,可以用粗类度的类图(类和类的关系)来表示,并加上必要的名词解释。

如果领域对象特别多,有必要建立分组。如何分而治之,可以参考DDD的界限上下文的分析方法。

领域模型是和技术无关的,所以,领域模型不等同于表设计,这里不应该出现表设计相关的内容。

领域模型非常重要,没有特殊情况,本部分必须要有。特殊情况请说明。

这部分可以与产品经理一起,紧密协作编写。

阅读全文 »
123…6
baiyang

baiyang

做海贼王的油腻男人

52 日志
3 分类
31 标签
RSS
GitHub
© 2020 baiyang
由 Hexo 强力驱动
主题 - NexT.Pisces
访问人数 总访问量 次