工厂+模板模式介绍及实战

应对需求扩展——简单工厂+模板模式实践 前言:软件设计开发需要关注需求的长期变化,SOLID(S-单一职责原则,O-开放封闭原则,L-里氏替换原则,I-接口隔离原则,D-依赖倒置原则)软件设计原则中,开闭原则是软件设计的重要方向。开闭原则即对扩展开放,对修改关闭,最简单的理解为:新增需求时,尽量通过新增代码(主要是新增类)而不是通过修改已有代码来实现,因为修改现有代码会引入新的不稳定因素,原本的单元测试也需要重新开展。设计模式是在特定场景下遵循设计原则的解决方案,学习并参考设计模式可以帮助新手了解如何写出易扩展、易维护的代码。...... 阅读详情

工厂+模板模式介绍及实战

1、设计模式介绍

1.1、工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

1.1.1、介绍

**意图:**定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

**主要解决:**主要解决接口选择的问题。

**何时使用:**我们明确地计划不同条件下创建不同实例时。

**如何解决:**让其子类实现工厂接口,返回的也是一个抽象的产品。

**关键代码:**创建过程在其子类执行。

应用实例: 1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。 2、Hibernate 换数据库只需换方言和驱动就可以。

优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。

**缺点:**每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

使用场景: 1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。 2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。

**注意事项:**作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

1.2、模板模式

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

1.2.1、介绍

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

**主要解决:**一些方法通用,却在每一个子类都重新写了这一方法。

**何时使用:**有一些通用的方法。

**如何解决:**将这些通用算法抽象出来。

**关键代码:**在抽象类实现,其他步骤在子类实现。

应用实例: 1、在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。 2、西游记里面菩萨定好的 81 难,这就是一个顶层的逻辑骨架。 3、spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存。

优点: 1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现。

**缺点:**每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

使用场景: 1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法。

**注意事项:**为防止恶意操作,一般模板方法都加上 final 关键词。

1.3、工厂模式和模板模式的区别

  • 模板模式属于行为型模式,工厂属于创建型模型;
  • 模板模式主要解决是众多接口实现问题;
  • 工厂模式是主要解决接口选择的问题。

2、工厂+模板设计模式实战

2.1、业务场景介绍

对接第三方服务服务,一共涉及到6个接口,特点如下:

  • 六个接口路径不一致,
  • 请求方式方法一致,
  • 请求参数字段名称一样,
  • 响应结构体一致,响应内容不一致。

2.2、代码实现

2.2.0、RuleType枚举

/**
 * @Author 
 * @Date 2022/8/21 10:24
 * @Description 类型
 * @Version 1.0
 */
public enum RuleType {

    /**
     * @Author 
     * @Date Created in 17:15 2022/8/21
     * @Description 
     * @Param
     * @return
     **/
    sift,

    /**
     * image
     * @Author 
     * @Date Created in 16:58 2022/8/30
     * @Description
     * @param
     * @return
     **/
    quote,

    /**
     * automate
     * @Author YangYaNan
     * @Date Created in 11:57 2022/8/8
     * @Description
     * @param
     * @return
     **/
    automate;

}

2.2.1、抽象基类BaseRuleType.java

/**
 * @author :
 * @date :Created in 11:21 2022/8/15
 * @description :
 * @version: 1.0
 */
@Service
@Slf4j
public abstract class BaseRuleType {

    @Getter
    public RuleType ruleType;

    @Autowired
    List<BaseRuleApi> baseRuleApis;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    RuleConfigRepo ruleConfigRepo;
    @Autowired
    QuoteRecordRepo quoteRecordRepo;


    /**
     * handlerRule核心逻辑
     * @Author YangYaNan
     * @Date Created in 19:13 2022/8/15
     * @Description
     * @param ruleDecorator 规则
     * @return void
     **/
    public abstract void handlerRule(IRuleDecorator ruleDecorator);

    /**
     * 解析规则结果
     * @Author 
     * @Date Created in 12:55 2022/8/8
     * @Description 目前使用
     * @param ruleDecorator 规则
     * @return java.lang.String
     **/
    public abstract void analyzeRuleData(IRuleDecorator ruleDecorator);

    /**
     * 挂载和ruleLog日志输出
     * @Author 
     * @Date Created in 14:40 2022/8/17
     * @Description
     * @param quoteProtocol 挂载属主
     * @param ruleDecorator 规则
     * @return void
     **/
    public abstract void mountAndPrintLog(QuoteProtocol quoteProtocol, IRuleDecorator ruleDecorator);

    /**
     * commonHandlerRule公共核心逻辑
     * @Author 
     * @Date Created in 19:13 2022/8/15
     * @Description
     * @param ruleDecorator
     * @return void
     **/
    public void commonHandlerRule(IRuleDecorator ruleDecorator){
        try {
            if (RuleInfoKey.RULE_NOT_GROUPID.equals(ruleDecorator.getRuleGroupId())) {
                log.info("[rule-{}-{}]不调用规则", ruleDecorator.getRuleType().toString(), ruleDecorator.getQuoteProtocol().getBusinessId());
                ruleDecorator.getRuleLog().setCallRule(false);
                return ;
            }
            baseRuleApis
                .stream()
                .filter(api -> api.supportType(ruleDecorator.getRuleType().toString()))
                .findFirst()
                .orElseThrow(() -> new CommonException(PARAMETER_ERROR.getCodeValue(), "暂不支持该类型规则"))
                .callRule(ruleDecorator);
            analyzeRuleData(ruleDecorator);
        }catch (Exception e) {
            log.error("[rule-{}-{}]调用规则异常:{},{}", ruleDecorator.getRuleType().toString(), ruleDecorator.getQuote().getBusinessId(), e.getMessage(), e.getStackTrace());
        }
    }

    void printLog(IRuleDecorator ruleDecorator) {
        ruleDecorator.getRuleLog().setEndAndConsumerTime(System.currentTimeMillis());
        log.info("[rule-{}-{}]ruleLog:{}", ruleDecorator.getRuleType().toString(), ruleDecorator.getQuote().getBusinessId(), CacheUtil.doJacksonSerialize(ruleDecorator.getRuleLog()));
    }

    public long getLongByInteger(Map dataMap, String ruleCoverageCode) {
        return dataMap.containsKey(ruleCoverageCode) ? ((Integer) dataMap.get(ruleCoverageCode)).longValue() : 1L;
    }

    public long getLongByDouble(Map dataMap, String ruleCoverageCode) {
        return dataMap.containsKey(ruleCoverageCode) ? ((Double) dataMap.get(ruleCoverageCode)).longValue() : 1L;
    }

    public double getDoubleByDouble(Map dataMap, String ruleCoverageCode) {
        return dataMap.containsKey(ruleCoverageCode) ? (Double) dataMap.get(ruleCoverageCode) : 1;
    }

    public double getDoubleByInteger(Map dataMap, String ruleCoverageCode) {
        return dataMap.containsKey(ruleCoverageCode) ? ((Integer) dataMap.get(ruleCoverageCode)).longValue() : 1;
    }

    public Object getObjectFromResultData(Map dataMap, String sendforinspectionLevel) {
        return dataMap.containsKey(sendforinspectionLevel) ? dataMap.get(sendforinspectionLevel) : "";
    }

    /**
     *  去掉首位逗号
     * @Author 
     * @Date Created in 16:26 2022/8/1
     * @Description
     * @param str 原字符串
     * @return java.lang.String
     **/
    public String startAndEndCommaRemove(String str) {
        String s = str.startsWith(",") ? str.replaceFirst(",", "") : str;
        return s.endsWith(",") ? s.substring(0, s.length() - 1) : s;
    }

    public boolean isValidNumber(String key) {
        String regx = "^\\d{4,6}$";
        boolean isNumber = Pattern.compile(regx).matcher(key).find();
        return isNumber;
    }

    void addAddActionRuleLog(RuleType.RuleTypeAction action, IRuleDecorator ruleDecorator, String ...changeInfoItems) {
        StringBuilder changeInfo = new StringBuilder();
        for (String s : changeInfoItems) {
            changeInfo.append(s).append("--");
        }
        ruleDecorator.addRuleLog(action.name(), changeInfo.toString());
    }


}

2.2.2、具体SiftType.java实现

/**
 * @author :
 * @date :Created in 11:24 2022/8/15
 * @description :
 * @version: 1.0
 */
@Service(value = "siftType")
@Slf4j
public class SiftType extends BaseRuleType {

    public SiftType(){
        this.ruleType = RuleType.sift;
    }

    @Override
    public void handlerRule(IRuleDecorator ruleDecorator) {
        commonHandlerRule(ruleDecorator);
    }

    /**
     * 解析规则返回data
     * @Author 
     * @Date Created in 11:56 2022/8/23
     * @Description 目前添加险种使用
     * @param ruleDecorator  报价
     * @return
     **/
    @Override
    public void analyzeRuleData(IRuleDecorator ruleDecorator){
        List<Suite> suites = ruleDecorator.getSuites();
        if (ObjectUtils.isEmpty(suites)){
            log.info("[rule-{}-{}]单交强不动态添加险种:{},{}", RuleType.sift.toString(), ruleDecorator.getQuoteProtocol().getBusinessId());
            return;
        }
        if (HttpStatus.HTTP_OK == ruleDecorator.getRuleResponse().getCode()) {
            HashMap<String, Boolean> ruleSupportSuitMap = RuleSupportSuitType.getRuleSupportSuitMap();
            suites.stream().forEach(suite -> { if (ruleSupportSuitMap.containsKey(suite.getCode())) { ruleSupportSuitMap.put(suite.getCode(), true); } });
            addSiftSuites(ruleDecorator, ruleSupportSuitMap);
            removeSiftSuites(ruleDecorator, ruleSupportSuitMap);
            updateSiftSuites(ruleDecorator, ruleSupportSuitMap);
            customizationSiftSuites(ruleDecorator, ruleSupportSuitMap);
        }
    }

    @Override
    public void mountAndPrintLog(QuoteProtocol quoteProtocol, IRuleDecorator ruleDecorator) {
        if (ObjectUtils.isNotEmpty(quoteProtocol.getBaseSuiteInfo()) && ObjectUtils.isNotEmpty(quoteProtocol.getBaseSuiteInfo().getBizSuiteInfo())) {
            quoteProtocol.getBaseSuiteInfo().getBizSuiteInfo().setSuites(ruleDecorator.getSuites());
            quoteProtocol.setSq(ruleDecorator.getSq());
        }
        printLog(ruleDecorator);
    }


    private void addSiftSuites(IRuleDecorator ruleDecorator, Map<String, Boolean> ruleSupportSuitMap) {
        //具体实现
    }

    private void customizationSiftSuites(IRuleDecorator ruleDecorator, Map<String, Boolean> ruleSupportSuitMap) {
        //具体实现
    }



    private void updateSiftSuites(IRuleDecorator ruleDecorator, HashMap<String, Boolean> ruleSupportSuitMap) {
        //具体实现
    }

    private void removeSiftSuites(IRuleDecorator ruleDecorator, HashMap<String, Boolean> ruleSupportSuitMap) {
        //具体实现
    }

}

2.2.3、具体AutomateType.java实现

/**
 * @author :
 * @date :Created in 11:28 2022/8/15
 * @description :
 * @version: 1.0
 */
@Service(value = "automateType")
@Slf4j
public class AutomateType extends BaseRuleType {

    public AutomateType() {
        this.ruleType = RuleType.automate;
    }

    @Override
    public void handlerRule(IRuleDecorator ruleDecorator) {
        commonHandlerRule(ruleDecorator);
    }

    @Override
    public void analyzeRuleData(IRuleDecorator ruleDecorator) {
        RuleResponse ruleResponse = ruleDecorator.getRuleResponse();
        String specialsStr= "";
        if (HttpStatus.HTTP_OK == ruleResponse.getCode()) {
            Map dataMap = ruleResponse.getData();
            specialsStr = dataMap.containsKey(RuleInfoKey.RULE_AUTOMATE_SPECIALLIST) ? dataMap.get(RuleInfoKey.RULE_AUTOMATE_SPECIALLIST).toString() : "";
            addAddActionRuleLog(RuleType.RuleTypeAction.add, ruleDecorator, specialsStr);
        }
        ruleDecorator.setSpecialInfos(specialsStr);
    }

    @Override
    public void mountAndPrintLog(QuoteProtocol quoteProtocol, IRuleDecorator ruleDecorator) {
        printLog(ruleDecorator);
    }


}

2.2.4、面向接口编程

/**
 * @author :
 * @date :Created in 10:23 2022/9/27
 * @description :
 * @version: 1.0
 */
public interface IRuleTypeFactory {

    /**
     * 获取接口类型
     * @Author 
     * @Date Created in 10:24 2022/9/27
     * @Description
     * @param ruleType 接口类型
     * @return com.cheche365.partner.service.impl.rule.type.BaseRuleType
     **/
    BaseRuleType getType(RuleType ruleType);

}

2.2.5、工厂RuleTypeFactoryImpl.java

/**
 * @author :
 * @date :Created in 10:28 2022/9/27
 * @description :
 * @version: 1.0
 */
@Service
public class RuleTypeFactoryImpl implements IRuleTypeFactory {

    @Resource(name = "siftType")
    private BaseRuleType siftType;
    @Resource(name = "quoteType")
    private BaseRuleType quoteType;
    @Resource(name = "automateType")
    private BaseRuleType automateType;
    @Resource(name = "insureType")
    private BaseRuleType insureType;

    private static Map<RuleType, BaseRuleType> typeMap = new HashMap<>();

    @PostConstruct
    public void intiRuleType() {
        typeMap.put(RuleType.sift, siftType);
        typeMap.put(RuleType.quote, quoteType);
        typeMap.put(RuleType.automate, automateType);
        typeMap.put(RuleType.insure, insureType);
    }

    @Override
    public BaseRuleType getType(RuleType ruleType) {
        return typeMap.get(ruleType);
    }
}

2.2.6、RuleManageServiceImpl.java

/**
 * @author :
 * @date :Created in 18:22 2022/9/18
 * @description :统一service层实现类
 * @version: 1.0
 */
@Service
@Slf4j
public class RuleManageServiceImpl implements IRuleManageService {

    @Autowired
    private List<BaseRuleType> baseRuleTypes;

    @Override
    public QuoteProtocol riskChangeRuleInfo(QuoteProtocol quoteProtocol) {
        IRuleDecorator ruleDecorator = new QuoteProtocolDecorator(quoteProtocol, RuleType.sift);
        BaseRuleType baseRuleType = baseRuleTypes.stream()
            .filter(api -> api.ruleType.equals(ruleDecorator.getRuleType()))
            .findFirst()
            .orElseThrow(() -> new CommonException(PARAMETER_ERROR.getCodeValue(), "暂不支持该类型"));
        baseRuleType.handlerRule(ruleDecorator);
        baseRuleType.mountAndPrintLog(quoteProtocol, ruleDecorator);
        return quoteProtocol;
    }
}
C++模板编程:从基础语法到泛型工厂实战 泛型编程是现代软件开发中实现代码复用与类型安全的核心技术,它通过参数化类型让同一套算法或数据结构能够处理多种数据类型。其原理是在编译期进行类型替换,生成针对特定类型的特化代码,从而实现零开销抽象,既保证了类型安全,又避免了运行时性能损耗。这一技术价值在于能够构建高度灵活、可复用的组件库,显著提升开发效率与代码质量。应用场景广泛,从标准模板库(STL)中的容器与算法,到设计模式中的工厂模式、策略模式实现,再到元编程中的编译期计算,都深度依赖泛型技术。本文以C++模板为具体载体,系统性地解析了函数模板、类模板、 阅读详情

相关推荐

C++教程(二):C++设计模式之工厂模式详细解析以及工厂模板类实现

在 C++ 中,工厂模式(Factory Pattern) 是一种创建型设计模式,它通过定义一个接口来创建对象,而不是直接实例化具体的类。这种模式的主要目的是将对象的创建过程封装起来,以便在不修改客户端代码的情况下轻松扩展新类型的对象。

a8598671的博客 1593

设计模式之模板模式和工厂模式

模板模式和工厂模式的类别分类为“交给子类”,即两种设计模式都是通过子类来实现具体的功能。主角是子类,而不像上次的适应设计模式,主角是连接器。这种差别着重体现在我们在工业设计中对需求的不同理解和实现。 以下例子选自《图解设计模式》 一,模板模式 概念 模板模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。这种算法...

lishinho的博客 5354

【C++实战㊷】C++ 原型模式实战:从概念到高效应用

本文聚焦 C++ 原型模式实战,先阐释其通过复制现有对象创建新对象的定义,说明对象创建成本高、需批量建相似对象等适用场景,介绍克隆方法及深浅克隆核心差异。接着讲解浅克隆、深克隆实现及原型管理器设计,分享深克隆递归实现、与工厂模式结合等实战技巧。最后以报表模板克隆系统为例,展示原型模式应用及效率测试,为开发者提供实用参考。

邓邓子的博客 1331

设计模式-04 工厂模式、模版模式

文章目录1.工厂模式1.1 Spring框架中工厂模式1.2 工厂模式优缺点2.模版模式2.1 什么是模版方法2.2 代码实现2.2.1 添加依赖2.2.2 启动类2.2.3 抽象类2.2.4 实现类2.2.5 工厂2.2.6 controller2.2.7 测试2.3 模式模式优缺点2.4 策略模式与模版方法模式的区别 1.工厂模式 工厂模式是为了解耦:把对象的创建和使用的过程分开。就是Cl...

沐宇熙IT成长之路 986

MMCV安装后报错‘from mmcv import Config’?别慌,这是MMCV 2.0的锅!快速降级回退MMCV 1.x全指南

本文详细解析了MMCV 2.0版本升级导致的‘from mmcv import Config’报错问题,提供了从诊断到降级回退MMCV 1.x的完整解决方案。通过pip和OpenMIM工具链的实操指南,帮助开发者快速解决版本冲突,确保项目稳定运行。

weixin_29102619的博客 263

2.4G射频微带线阻抗匹配设计实战(WiFi/BLE)

本文深入探讨了2.4G射频微带线阻抗匹配在WiFi/BLE产品开发中的关键作用。文章详细解析了共面波导微带线结构,提供了基于SI9000工具的阻抗计算实战指南,并总结了不同PCB板厚下的设计参数对照表。同时,文章分享了PCB布局布线、与板厂沟通以及天线匹配调试等核心避坑经验,旨在帮助硬件工程师构建从射频芯片到天线的稳定高效传输通道。

j0k1l2m3n的博客 369

玩转3 种高频设计模式——模板+策略+工厂模式

设计模式

Gorden的博客 1287

STRING数据库的蛋白质相互作用(PPI)网络分析

在转录调控相关的文献中,我们经常能够看到这样的蛋白质相互作用网络(protein protein interaction network,PPI network)。具体而言,这些相关的文献中首先通过RNA-seq、表达谱芯片或者蛋白质组分析等,找到了在不同分组样本间一系列的差异表达基因或蛋白。

weixin_43029125的博客 9458

设计模式 详解

设计模式(工厂模式、单例模式、模板模式) 简单工厂模式: 1.概述:工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程(new关键字和具体的构造器)隐藏起来,用一个工厂方法来代替,对外提供的只是一个工厂方法,达到提高灵活性的目的。 2.优点: 1.隐蔽了new关键字和构造器 2.降低了这个对象与别的类之间的耦合度,提高了程序的可扩展性 ...

weixin_30690833的博客 213

【Qt】Qt6系列教程汇总_qt6教程

简介:QT相关电子书、建议和相关参考网址。

2401_87556657的博客 1187

紫光PG2L100H平台DDR3 IP核调试实战:从AXI接口到状态机设计的避坑指南

本文详细介绍了在紫光PG2L100H FPGA平台上调试DDR3 IP核的实战经验,重点解析了AXI接口的特殊行为和状态机设计的关键技巧。通过具体代码示例和调试方法,帮助开发者规避常见陷阱,实现高性能DDR3控制器设计,达到1.2GB/s的稳定带宽。

weixin_28717969的博客 219

23种设计模式——工厂模式完全指南:点外卖征服汉堡工厂

《工厂模式实战指南:用披萨外卖理解设计模式》 本文通过生动类比,将工厂模式比作外卖点餐系统,通俗易懂地讲解了这一设计模式的核心思想。文章首先揭示工厂模式的本质是"需要对象时不用自己创建",接着通过披萨工厂的完整代码示例,展示了从产品接口到具体实现再到工厂类的完整结构。文中详细对比了工厂模式三大家族(简单工厂、工厂方法和抽象工厂)的区别,并总结了五大优势:封装创建逻辑、解耦客户端、易于扩展、统一管理和面向接口编程。最后提供了面试黄金回答模板,帮助读者掌握实际应用场景。全文用生活化的比喻和清

qq_52077555的博客 1145

微带功分器设计与ADS-EM联合仿真实战解析

本文详细解析了微带功分器设计与ADS-EM联合仿真的实战技巧,涵盖特性阻抗计算、ADS原理图设计、版图生成与EM仿真等关键步骤。通过实际案例分享,帮助工程师掌握射频电路设计中的核心技术和调试方法,提升功分器设计效率与性能。

weixin_29280219的博客 452

简单工厂模式

简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern),简单来说,简单工厂模式有一个具体的工厂类,可以生成多个不同的产品,属于创建型设计模式。简单工厂模式不在GoF 23种设计模式之列。对于产品种类相对较少的情况,考虑使用简单工厂模式可以很方便地创建所需产品。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑。

SunnyRivers 822

Dify知识库文档批量下载神器:一键导出所有文件到本地

在使用Dify进行知识库管理的过程中,我们经常遇到一个实际问题:如何将已上传到知识库中的文档批量下载到本地?目前Dify的管理界面虽然功能强大,但暂时没有提供直接的UI界面来批量导出或下载知识库内的文档。这意味着如果我们需要将知识库中的文件备份到本地或进行离线处理,只能通过API接口来实现。本文将详细介绍如何利用Dify的REST API构建一个完整的知识库文档下载解决方案,这也是目前实现知识库文件批量下载到本地的唯一可行路径。🎉进入大模型应用与实战专栏 | 🚀查看更多专栏内容首先,我们需要在Dify的

羊城迷鹿的博客 3474

QGIS将经纬度坐标转成点

QGIS绘制一张地图

weixin_46713695的博客 6056

工厂方法模式

工厂方法模式(Factory Method Pattern)又叫作多态性工厂模式,指定义一个创建对象的接口,但由实现这个接口的类来决定实例化哪个类,工厂方法把类的实例化推迟到子类中进行。工厂方法模式主要适用于以下应用场景。(1)创建对象需要大量重复的代码。(2)客户端(应用层)不依赖产品类实例如何被创建、实现等细节。(3)一个类通过其子类来指定创建哪个对象。

SunnyRivers 1073

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)指提供一个创建一系列相关或相互依赖对象的接口,无须指定它们具体的类。意思是客户端不必指定产品的具体类型,创建多个产品族中的产品对象。与工厂方法模式相比,抽象工厂模式可以创建一组相关的对象,而不是单一的对象。在抽象工厂模式中,客户端(应用层)不依赖产品类实例如何被创建、实现等细节,强调一系列相关的产品对象(属于同一产品族)一起创建对象,需要大量重复的代码。需要提供一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖具体实现。

SunnyRivers 954

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

建造者模式

建造者模式(Builder Pattern)将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,属于创建型设计模式。对于用户而言,使用建造者模式只需指定需要创建的类型就可以获得对象,创建过程及细节不需要了解。根据建造者模式的定义,可以简单地理解为两层含义。(1)构建与表示分离:构建代表对象创建,表示代表对象行为、方法,也就是将对象的创建与行为进行分离(对应到Java代码,其实就是使用接口规定行为,然后由具体的实现类进行构建)。

SunnyRivers 1378

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

实战python设计模式_实战Python设计模式:可复用面向对象软件开发实践

目录第1 章 示例软件介绍 ··········································································· 11.1 准备工作 ············································································ 11.1.1 源代码下载 ··········...

weixin_31995467的博客 208

C++模板编程:从函数模板到泛型工厂的完整指南

泛型编程是C++中实现代码复用的核心技术,它允许开发者编写独立于数据类型的通用算法和数据结构。其核心原理是通过模板在编译期生成针对具体类型的特化代码,从而在保证类型安全的同时消除代码冗余。这一技术为构建高效、可维护的软件系统提供了巨大价值,广泛应用于标准模板库(STL)中的容器(如vector、map)和算法(如sort、find)。在工程实践中,模板不仅能实现简单的函数模板和类模板,还能通过模板特化、可变参数模板等高级特性处理复杂场景,例如构建泛型工厂模式。本文以C++模板为核心,深入解析了模板元编程(T

weixin_32430941的博客 265

C++14变量模板实战:从编译期常量到单例工厂的避坑指南

模板是C++泛型编程的核心,它允许编写独立于特定类型的通用代码。其原理是通过编译器在编译时根据具体类型生成特化版本,实现类型安全且高效的代码复用。这一技术价值在于提升代码的抽象能力和性能,广泛应用于基础库、算法容器和元编程等领域。变量模板作为C++14引入的特性,进一步扩展了模板的能力,允许定义类型相关的常量或变量,是实现编译期计算和类型分发的重要工具。然而,在实际工程中,开发者常因对其链接规则和常量性理解不足而陷入陷阱,例如在头文件中定义非const变量模板导致多重定义错误,或混淆constexpr变量模

weixin_30843121的博客 240

一文整合工厂模式、模板模式、策略模式

其实这几个设计模式我们在平常开发中非常容易使用,也可能你一直在使用就是没有留意而已。

weixin_43741322的博客 3796

【设计模式】工厂模式之模板工厂模式详解

模板工厂模式(Template Factory)是泛型编程与工厂模式的完美结合,利用C++模板特性实现编译期多态和零开销抽象,尤其适合高性能、强类型场景。

浩瀚之水的专栏 1068

设计模式——简单工厂模型、工厂模式、抽象工厂模式、单例模式、代理模式、模板模式

模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。其主要分为两大类:模版方法和基本方法,而基本方法又分为:抽象方法(Abstract Method),具体方法(Concrete Method),钩子方法(Hook Method)。四种方法的基本定义(前提:在抽象类中定义):(1)抽象方法:由抽象类声明,由具体子类实现,并以abstract关键字进行标识。(2)具体方法:由抽象类声明并且实现,子类并不实现或者做覆盖操作。其实质就是普遍适用的方法,不需要子类来实现。

qq_44182424的博客 1713

C++设计模式之模板工厂模式

工厂模式一般分为简单工厂模式,工厂方法模式,抽象工厂模式,不过今天我介绍的是由模板实现的工厂模式,可以实现产品类自动注册到对应的工厂类,完全解耦,并且提供工厂单例访问。 fantory.h #pragma once #include <map> #include <string> //产品工具抽象类 template<class AbstractProduct...

github_39553168的博客 1607
上一篇: 模板+策略设计模式介绍及实战
下一篇: 责任链设计模式介绍及实战
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白de成长之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值