首页 > 其他分享 >软件开发原则

软件开发原则

时间:2023-09-04 20:44:34浏览次数:43  
标签:remoteUrl 软件开发 原则 fileKey param 接口 return String

软件开发原则

原则 介绍
单一职责原则 一个类或模块应该只负责一项任务或功能
开闭原则 软件实体(类、模块、函数等)应该对扩展开放,对修改关闭
里氏替换原则 子类应该能够替换其父类并且不会破坏程序的正确性
接口隔离原则 客户端不应该强制依赖它不需要的接口,即应该将接口拆分成更小的部分
依赖倒置原则 高层模块不应该依赖于底层模块,它们都应该依赖于抽象接口
迪米特法则 一个类应该对自己需要耦合或调用的类知道得最少(提供最简化调用接口)
聚合复用原则 尽量使用对象组合,而不是继承来达到复用的目的

以我个人的开源项目举例,来介绍几个基本软件开发原则的基本使用

【SpringBoot集成OnlyOffice实现文档预览】

单一职责原则

模块的单一职责

该开源项目可以作为一个jar引入,其承担的职责就是对onlyoffice集成,实现对office文件的预览和编辑。在领域驱动设计中,每个领域对象和聚合根通常应该遵循单一职责原则,确保它们只负责一个明确定义的领域职责。这有助于保持领域模型的清晰性,同时也符合单一职责原则的要求。

类的单一职责

我定义了如下几个接口类,其中每个类只负责了单一的职能

存储服务接口

package org.lboot.onlyoffice.loader;

import org.lboot.onlyoffice.domain.Document;

import java.io.InputStream;

/**
 * @author kindear
 * office 文档存储服务
 * 该服务与第三方或者本地文件系统集成
 */
public interface OfficeStoreLoader {
    /**
     * 根据文件 key 获取文件信息
     * @param fileKey
     * @return
     */
    Document readFile(String fileKey);

    /**
     * 修改文件
     * @param fileKey
     * @param stream
     * @return
     */
    boolean writeFile(String fileKey, InputStream stream);

}

鉴权服务接口

package org.lboot.onlyoffice.loader;

/**
 * @author kindear
 * Office 鉴权信息加载
 */
public interface OfficeAuthLoader {
    /**
     * 获取当前登录用户ID
     * @return
     */
    default String getUserId(){
        return "0";
    }

    /**
     * 获取当前登录用户名称
     * @return
     */
    default String getUserName(){
        return "guest";
    }
}

配置接口

package org.lboot.onlyoffice.loader;

/**
 * @author kindear
 * OnlyOffice配置加载
 */
public interface OfficeConfigLoader {
    /**
     * 获取客制化LOGO地址
     * @return
     */
    @Deprecated
    default String getCustomLogo(){
        return "";
    }

    /**
     * 获取默认语言
     * 默认 zh-CN 中文
     * @return
     */
    default String getLang(){
        return "zh-CN";
    }

    /**
     * 获取回调地址
     * @return
     */
    default String getCallbackUrl(){
        return "";
    }

}

开闭原则

对扩展开放,对修改关闭

将我的项目作为依赖引入后,自然而然符合对修改关闭这个特点,

集成的业务系统又可以基于上面所定义的接口,来拓展实现功能,满足对拓展开放

具体可以查看【拓展】

里氏替换原则

子类可以扩展父类的功能,但不能改变父类原有的功能

我在代码设计中加入了基于spring上下文的事件监听机制,该子类继承自父类ApplicationEvent,该实现没有改变父类可以被spring框架管理监听的特性,又拓展了新的字段属性,使得该子类可以在被spring管理监听的基础上,携带了更多参数。

package org.lboot.onlyoffice.event;

import lombok.Getter;
import org.springframework.context.ApplicationEvent;

import java.time.Clock;

/**
 * @author kindear
 * office 文档编辑构建事件 传入文件ID 和 用户ID
 */
@Getter
public class OfficeEditBuildEvent extends ApplicationEvent {
    String userId;

    String fileKey;

    public OfficeEditBuildEvent(Object source, String userId, String fileKey) {
        super(source);
        this.userId = userId;
        this.fileKey = fileKey;
    }

    public OfficeEditBuildEvent(Object source, Clock clock) {
        super(source, clock);
    }
}

接口依赖原则

接口仅仅提供客户端需要的行为,即所需的方法,客户端不需要的行为则隐藏起来,应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口

在完成配置项后,不需要用户关注底层的编辑回调,文件装载,文件信息获取如何实现,该依赖为用户提供了最简单的调用接口OfficeCtl,所有引入该依赖的,都只需要该类即可。

package org.lboot.onlyoffice.service;

import org.lboot.onlyoffice.domain.DocEditor;
import org.lboot.onlyoffice.domain.Document;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @author kindear
 * onlyoffice 服务实现类
 */
public interface OfficeCtl {
    /**
     * 根据文件后缀 获取office 中类型
     * @param extName
     * @return 文件类型
     */
     String getDocumentType(String extName);

    /**
     * 构建远程文档访问 Document
     * @param remoteUrl
     * @return
     */
     Document buildRemoteDocument(String remoteUrl);

    /**
     * 构建文档预览 DocEditor
     * @param document
     * @return
     */
     DocEditor buildPreviewDocEditor(Document document);

    /**
     * 构建文档编辑 DocEditor
     * @param document
     * @return
     */
     DocEditor buildEditDocEditor(Document document);

    /**
     * 预览远程文件
     * @return file-temp
     */
    @Deprecated
    ModelAndView previewRemoteFile(String remoteUrl, HttpServletResponse servletResponse);

    /**
     * 预览远程文件
     * @param remoteUrl
     * @return
     */
     ModelAndView previewRemoteFile(String remoteUrl);

    /**
     * 移动端预览远程文件
     * @param remoteUrl
     * @return
     */
     ModelAndView previewRemoteFileOnMobile(String remoteUrl);

    /**
     * 嵌入式预览远程文件
     * @param remoteUrl
     * @return
     */
     ModelAndView previewRemoteFileOnEmbedded(String remoteUrl);

    /**
     * 根据文件key 预览文件
     * @param fileKey
     * @return 预览试图
     */
     ModelAndView previewFile(String fileKey);

    /**
     * 文件预览
     * @param editor
     * @return
     */
    ModelAndView previewFile(DocEditor editor);

    /**
     * 文件预览 制定预览标题
     * @param editor
     * @param title
     * @return
     */
    ModelAndView previewFile(DocEditor editor, String title);


    /**
     * 编辑远程文件
     * @param remoteUrl
     * @return
     */
    ModelAndView editRemoteFile(String remoteUrl);



    /**
     * 文件编辑
     * @param fileKey
     * @return
     */
    ModelAndView editFile(String fileKey);

    /**
     * 文件编辑
     * @param document
     * @return
     */
    ModelAndView editFile(Document document);

    /**
     * 文件编辑
     * @param editor
     * @return
     */
    ModelAndView editFile(DocEditor editor);



    /**
     * 编辑回调
     * @param params
     * @return
     */
    Object editCallback(Map<String,Object> params);

    /**
     * 将远程访问文件转化为 Pdf
     * @param remoteUrl
     * @return pdf 下载地址
     */
    String covertToPdf(String remoteUrl);

    /**
     * 将文件转化未 pdf
     * @param document
     * @return
     */
    String covertToPdf(Document document);


    /**
     * 文件生成缩略图
     * @param remoteUrl
     * @return
     */
    String generateThumbnail(String remoteUrl);

    /**
     * 文件生成缩略图
     * @param document
     * @return
     */
    String generateThumbnail(Document document);

}

依赖倒置原则

高层模块不应该依赖于底层模块,它们都应该依赖于抽象接口

OfficeCtl接口的实现举例,注入的接口全都是抽象接口,无论是基于默认的服务实现还是拓展实现,都可以注入。

@Slf4j
@Service
@AllArgsConstructor
public class OfficeCtlImpl implements OfficeCtl {
    OnlyOfficeProperties officeProps;

    OfficeConfigLoader configLoader;

    OfficeAuthLoader authLoader;

    OfficeStoreLoader storeLoader;

    @Resource
    ApplicationContext context;
    
    //...
}

迪米特法则

一个类应该对自己需要耦合或调用的类知道得最少(提供最简化调用接口)

例如读取本地存储系统文件并预览的接口

 	@SneakyThrows
  	@Override
    public ModelAndView previewFile(String fileKey) {
        Document document = storeLoader.readFile(fileKey);
        DocEditor docEditor = buildPreviewDocEditor(document);
        return previewFile(docEditor);
    }

我们只需要关注调用storeLoader.readFile(fileKey);可以获取对应的信息,对于该接口中如何获取文件并读取信息的实现不需要关注。

合成复用原则

OfficeCtl的实现类即是几种服务的合成复用的案例

标签:remoteUrl,软件开发,原则,fileKey,param,接口,return,String
From: https://www.cnblogs.com/masterchd/p/17678048.html

相关文章

  • 软件开发原子化 技术转型加速器
    在万物互联的时代,人均持有设备量不断攀升,设备和场景的多样性,每个设备都需要独立开发一个应用,先安装后使用、不同设备的能力不兼容等传统应用的短板逐步暴露出来。在此背景下,应用提供方和用户都迫切需要一种新的服务提供方式,使应用开发更简单、服务的获取和使用更便捷,原子化服务也......
  • 软件开发原子化 技术转型加速器
    在万物互联的时代,人均持有设备量不断攀升,设备和场景的多样性,每个设备都需要独立开发一个应用,先安装后使用、不同设备的能力不兼容等传统应用的短板逐步暴露出来。在此背景下,应用提供方和用户都迫切需要一种新的服务提供方式,使应用开发更简单、服务的获取和使用更便捷,原子化服务也就......
  • 正则的匹配原理以及优化原则
    正则之所以能够处理复杂文本,就是因为采用了有穷状态自动机(finiteautomaton)。那什么是有穷自动机呢?有穷状态是指一个系统具有有穷个状态,不同的状态代表不同的意义。自动机是指系统可以根据相应的条件,在不同的状态下进行转移。从一个初始状态,根据对应的操作(比如录入的字符集)执行状态......
  • 软件开发必读!华为云软件开发生产线CodeArts深度体验指南
    7月7日-9日,随着华为开发者大会2023的到来,华为云软件开发生产线CodeArts也走进了很多开发者的视野。开发者都比较好奇,什么是华为云CodeArts?CodeArts都有什么功能?在软件开发中能起到什么作用?CodeArtssnap是否有介绍的那般神奇?本文将为各位开发者详细介绍如何从了解学习到体验掌握华......
  • 设计模式学习1 设计原则
    设计原则1.开闭原则对扩展开放,修改关闭。在程序需要扩展的时候,不能去修改原有代码,实现一个热插拔的效果。为了使程序的扩展性好,易于维护和升级为了达到这样的效果,我们需要使用接口和抽象类2.里氏代换原则任何基类可以出现的地方,子类一定可以出现。也就是子类继承父类时,除了添......
  • 三位一体的软件开发成功之道
    在当今数字化时代,产品架构、应用架构和技术架构是构建现代化软件系统的关键要素。它们相互关联,共同影响着软件产品的功能、性能和可扩展性。本文将深入探讨产品架构、应用架构和技术架构之间的关系,并阐明它们在软件开发中的重要性。 一、产品架构产品架构是指在软件产品设计......
  • 软件开发常说的CI/CD是什么
    本文翻译自国外论坛medium,原文地址:本文翻译自国外论坛medium,原文地址:https://medium.com/gitconnected/basics-of-ci-cd-a98340c60b04任何软件项目的主要目标都是通过业务流程快速更新迭代来赚钱。我们越快向客户发布新版本,对我们的公司就约有好处。但如何快速实现版本更新迭代......
  • [读书笔记]架构设计原则
    架构设计面向的是不确定性,需要面对多种可能性时进行选择。选择的前提是知识和经验,知识是指有哪些技术、可用组件、实现思路等,这个决定了可选的范围。经验是对当前的业务、情形进行分析,能识别对当前的工作最有效的要素,能从选择空间里做出选择。多学习:扩大可选择的空间和范围多......
  • 直播软件开发,点击屏幕隐藏键盘的正确写法
    直播软件开发,点击屏幕隐藏键盘的正确写法方法一: -(void)touchesBegan:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event{  [self.viewendEditing:YES];}​方法二: -(void)touchesEnded:(NSSet*)toucheswithEvent:(UIEvent*)event{  [self.userName......
  • 趣解开闭原则之《我发誓!再也不买一体机了》
    〇、小故事小王大学毕业后,找了一份像样的工作,早八晚五轻松自在,并且收入也不错。自从大学毕业后,家里用的电脑还是他上大学的时候用了四年的电脑,配置性能早已跟不上现在的时代了。他决定用自己赚的工资买一台家用电脑。他咨询了他的好朋友,好多人都建议他买一台苹果的一体机,所有硬件......