• Home
  • Archives
  • 随笔
所有文章 友链 关于我

  • Home
  • Archives
  • 随笔

设计模式详解

发布于: 2021-05-31
更新于: 2023-07-09

设计模式

面向对象

OOP笔记

工厂方法

Factory method Pattern 实现了“工厂”概念的面向对象设计模式。定义一个创建对象的接口,但让实现这个接口的类决定实例化哪个类。
通俗的说法:女朋友想要可乐,你需要体贴的问她要百事还是可口可乐吗?不需要把,你只需要和服务员说来瓶可乐即可。服务员会自动拿百事可乐或者可口可乐

classDiagram
Cola <|-- CocoCola: 实现可乐接口
Cola <|-- PeisiCola: 实现可乐接口
Cola: object cola
Cola: getCola()

GirlFriend --> Cola: 女主子要可乐
package com.tyrantqiao.algorithms.pattern;

import com.tyrantqiao.algorithms.pattern.shape.Circle;
import com.tyrantqiao.algorithms.pattern.shape.IShape;
import com.tyrantqiao.algorithms.pattern.shape.Triangle;

import java.lang.reflect.InvocationTargetException;

/**
 * date: 2018/4/30
 * Description: 工厂模式
 * blog https://tyrantqiao.github.io/Blog
 * <p>
 * 解决的什么问题:
 * 比如说现在要cricle.paint()
 * 在God类中{@code Shape circle=new Circle();}
 * {@code circle.paint();}
 * 假如说要加多个triangle.paint();
 * 就要多定义一个 {@code Shape triangle=new Triangle();
 * triangle.paint();}
 * 导致God类依赖严重,臃肿
 * <p>
 * 解决方法就是通过工厂方式,God Class不关心具体实现Shape的细节,只管把自己想要的东西告诉{@link FactoryPattern}的getShape()方法
 *
 * @author tyrantqiao
 * @version 0.0.1
 * @see <a href="https://github.com/tyrantqiao">qiao's github</a>
 */
public class FactoryPattern {

    enum ShapeEnum {
        /**
         * 圆形
         */
        CIRCLE("circle"), Triangle("triangle");

        private final String shapes;

        ShapeEnum(String shapes) {
            this.shapes = shapes;
        }

        public String getShape() {
            return shapes;
        }
    }


    /**
     * @param shapeType 形状类型
     * @return 获取类型
     * @apiNote 存在问题,每次加类型都要修改这个方法,后期容易臃肿,改进为反射进行获取类
     */
    public IShape getShape(String shapeType) {
        if (ShapeEnum.CIRCLE.getShape().equals(shapeType)) {
            return new Circle();
        } else if (ShapeEnum.Triangle.getShape().equals(shapeType)) {
            return new Triangle();
        }
        return null;
    }

    /**
     * 进化版,根据类去实例化
     *
     * @param clazz 类
     * @return 实例化后的类
     */
    public IShape getShapeVersionTwo(Class<? extends IShape> clazz) {
        try {
            if (null != clazz) {
                // 假如是内部类的话,此段代码无法运行,请注意
                return clazz.getDeclaredConstructor().newInstance();
            }
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }
}

抽象工厂

抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来
俗话: 还是女票主子,出去玩总得化个美美的妆把,化妆就又需要口红,眉笔,腮红,粉底,眼线·····除了这些化妆品外,还讲究化妆的风格流派,是哥特萝莉派,还是生人勿近的女神派,这些需要的色号以及化妆品牌子型号又不同。
那怎么快速管理这些风格呢?土豪流派(抽象工厂):把每一个流派所需的化妆品放到一个化妆盒子里,这样子只要打开对应盒子,即可以拿到对应流派的化妆品

classDiagram
class GirlFriend {
    factory: AbstractCosmeticFactory
}

GirlFriend: GirlFirend(AbstractCosmeticFactory)
GirlFriend: makeUp()

class AbstractCosmeticFactory{
    <<interface>>
    getLipstick() Lipstick
    getEyebrowPencil()  EyebrowPencil
}

class GothicCosmeticFactory{
    <<哥特风>>
    getLipstick() return new GothicLipstick()
    getEyebrowPencil()  return new GothicEyebrowPencil()
}

class PureCosmeticFactory{
    <<清纯风>>
    getLipstick() return new  PureLipstick()
    getEyebrowPencil() return new EyebrowPencil()
}

class Lipstick{
    <<口红接口基类>>
}

class GothicLipstick{
    <<哥特风口红>>
}

class PureLipstick{
    <<清纯口红>>
}

Lipstick <|.. GothicLipstick: 继承
Lipstick <|.. PureLipstick: 继承

GirlFriend --* AbstractCosmeticFactory: 通过抽象工厂类获取化妆品
 AbstractCosmeticFactory <|.. GothicCosmeticFactory : 实现接口
 AbstractCosmeticFactory <|.. PureCosmeticFactory : 实现接口

GothicCosmeticFactory --> GothicLipstick: return new GothicLipstick()
PureCosmeticFactory --> PureLipstick: return new PureLipstick()

建造者模式

对象构建模式。将复杂对象的构建过程抽象出来,使抽象过程的不同实现方法可以构建出不同的对象。
俗话:都知道女朋友是一种神奇的主子生物,心情和天气一样阴晴不定,那么我们如何抉择怎么讲话呢?比如说我们有一个骚话模板计算器,有讲笑话,讲故事,出去吃饭等功能,不同的组合形式,不同的执行顺序都会影响到女朋友的心情。
重点来了:把这些骚话抽象成一个个按钮,按 1 是讲笑话,按 2 是讲故事,按 3 是出去吃饭,有了这些按钮,我们可以随意排列这些顺序 123、312,或者选择性挑选 31、23,都能生成一个很好和女朋友玩耍的操作模板。

Department department=new Department.Builder("数据库部门","3306")
                            .setMembers(···)
                            .setInstruments(···)
                            .build();

public class Department{
    private String[] members;
    private String[] instruments;
    /**
     * name 和 id必输
     */
    private String name;
    private String id;

    private Department(Builder builder){
        this.name=builder.name;
        this.id=builder.id;
    }

    public static class Builder{
        private String[] members;
        private String[] instruments;
        /**
         * name 和 id必输
         */
        private String name;
        private String id;

        private Builder(String name,String id){
            this.name=builder.name;
            this.id=builder.id;
        }

        public Builder setMembers(String[] members){
            this.members=members;
            return this;
        }

        public Builder setInstruments(String[] instruments){
            this.instruments=instruments;
            return this;
        }

        public Department build(){
            return new Department(this);
        }
    }
}

原型模式

创建型模式的一种,通过复制一個已經存在的實例來返回新的實例, 而不是新建實例。被复制的实力成为原型
俗话怎么说呢,把对象引用当作一个自动回复消息模板,比如说你想自动回复“我在忙,别打扰我”,但是你不想每次都手打,那你可以选择《忙碌模板》进行快速回复,原型模型的目的就是为了快速的复制,毕竟不涉及内容的真正变更,只是浅复制 shallow copy 关于浅复制和深复制的请参考这篇文章

classDiagram

class Client{
    <<God class>>
}

Client: operation() ==> prototype.clone()

class Prototype{
    <<interface>>
}

class ConcretePrototype1{
    <<实现类1>>
}

class ConcretePrototype2{
    <<实现类2>>
}

Prototype *-- Client: import class
Prototype <|-- ConcretePrototype1: 继承
Prototype <|-- ConcretePrototype2: 继承

单例模式

在應用這個模式時,單例對象的類必須保證只有一個實例存在。許多時候整個系統只需要擁有一個的全局對象,這樣有利於我們協調系統整體的行為—wiki
俗话:只有一个你

classDiagram

class Client{
    <<客户类>>
}
class Singleton{
    <<单例模式>>
    instance: Singleton
}

Singleton: -Singleton()
Singleton: +getInstance() Singleton

Client --* Singleton: import
Singleton --> Singleton: 返回单一实例

适配器模式(变压器模式)

(Adapter)配接器模式有時候也稱包裝樣式或者包裝。將一個類別的介面轉接成用戶所期待的.
俗话: 你在和外国友人吹水,但是语言不通(相当于接口不通),这时来了个自动翻译软件(适配器),大家就能交谈了。

对象适配器

适配器实现了其中一个对象的接口,并将另一个对象进行封装

classDiagram
class Client{
    <<God class>>
}

class ClientInterface{
    <<interface>>
    +method(data)
}

class Service{
    <<Service 不适配的服务>>
    +serviceMethod(specialData)
}

class Adapter{
    <<适配器模型>>
    adaptee: Service
    +method(data)
}

Client --> ClientInterface: 原本引入的接口
Adapter --|> ClientInterface: 继承原有接口,便于后面无缝切换
Adapter --* Service: 组合封装服务类
Client ..> Adapter: 等Adapter开发完后,迁移到这

类适配器

通过继承机制,同时继承两个对象的接口。但只能支持多重继承,比如 C++

classDiagram
class Client{
    <<上帝类>>
}

class ExistingClass{
    <<原有服务>>
    +method(data)
}

class Service{
    <<不适配的服务>>
    +serviceMethod(specialData)
}

class Adapter{
    +method(data)
}

Client --* ExistingClass: import
Adapter --|>  ExistingClass: 继承
Adapter --|>  Service: 继承
Client ..> Adapter: 等改造完后进行迁移

桥梁模式

它把事物對象和其具體行爲、具體特徵分離開來,使它們可以各自獨立的變化。事物對象僅是一個抽象的概念–wiki
俗话:比如说化妆,你需要打理头发,同时也需要整理妆容,这两个都要根据不同的场景进行适配,通过桥梁模式,把抽象和实现分离,这样子就可以让打理头发,整理妆容适配场景

classDiagram
class Pen{
    <<abstract>>
    color: 颜色
    +setColor(Color) abstract
    +paint() abstract
}

class PurePen{
    <<纯粹笔>>
    +paint() implements
}

class Color{
    <<abstract>>
    +color() abstract
}

class RedColor{
    <<红色>>
    +color() implements
}

Pen <|-- PurePen: 继承实现笔型号变换
Pen --* Color: 组合color的抽象类
Color <|-- RedColor: 继承实现具体颜色

合成模式

合成模式(Composite Pattern),又叫部分整體模式,是用於把一組相似的對象當作一個單一的對象
俗话:
“请我吃一道麦当劳把”
“可以啊,只能一道”
“哎哎哎,怎么还点汉堡鸡块可乐薯条了,这都四样了”
“四个刚好组一起作为套餐啊”

graph TD;
    root -->|tmp文件夹| tmp
    root -->|log文件夹| log
    log --> |按年份查询| 2021
    log --> |按年份查询| 2020
    title[文件系统,每一个文件和目录都是视为文件,即root目录和2021等效]

代理模式

通过代理人 proxy 为其他对象提供代理,以控制对对象的访问。起到保护目标对象+增强目标对象的作用。

classDiagram
class Subject{
    +request() void
}

class Proxy{
    Proxy(Subject)

    +request() void
    +before() void
    +after() void
}

class RealSubject{
    +request() void
}

class Client{
    +main(String[] args) void
}

RealSubject<..Client: create
Proxy<..Client: create
Subject<|--|>Proxy: 1-1
Subject<|..RealSubject

参考资料

  1. 设计模式通俗
  2. <<设计模式之禅>>
设计模式详解
/archives/a59a9302/
作者
tyrantqiao
发布于
2021-05-31
更新于
2023-07-09
许可协议
CC BY-NC-SA 4.0
赏

蟹蟹大佬的打赏,大家一起进步

支付宝
微信
  • 面经
  • 设计模式

扫一扫,分享到微信

微信分享二维码
如何打造精美的github profile界面
强推好用的软件插件以及配置项
© 2024 tyrantqiao 本站总访问量次 本站访客数人次 载入天数...载入时分秒...
  • 所有文章
  • 友链
  • 关于我

tag:

  • 复盘
  • 我
  • 规划
  • java
  • 面试
  • 源码
  • 架构
  • Hadoop
  • HTTP
  • TCP
  • 学习笔记
  • IDEA
  • maven
  • idea
  • Java
  • jdk
  • 面经
  • linux
  • 爱情
  • mysql
  • 性能
  • sql
  • Mysql
  • JAVA
  • 技术
  • Redis
  • MQ
  • Spring
  • 数据库
  • TIDB
  • spring
  • unity
  • chatgpt
  • 经验分享
  • 前端
  • redis
  • vue
  • git
  • shadowsocks
  • hexo
  • blog
  • bug
  • 开发
  • 业务
  • jvm
  • 算法
  • MySQL
  • nginx
  • Linux
  • mq
  • db
  • springCloud
  • ssh
  • python
  • 爬虫
  • test
  • vim
  • 影视剧
  • 中间件
  • 事务
  • 性格
  • 音乐
  • 程序员
  • 随笔
  • mybatis
  • 演讲
  • 域名
  • 猫咪
  • 她
  • github
  • 计划
  • 旅游
  • 软件
  • 心理
  • 情商
  • 幽默
  • 才艺
  • 穿搭
  • 编程
  • 排序
  • 查找
  • 缓存
  • 网络
  • 设计模式
  • c
  • 课程设计
  • centos
  • 数学
  • 本网站主题yilia设计者的主页
如果有问题或者想讨论的可以联系[email protected]或者[email protected]