手里拿着锤子,看啥都像钉子

简介: 手里拿着锤子,看啥都像钉子

一、背景

有人在我的构造器文章下提了下面一个问题:

老师,提一个问题,在实际生活中遇到的 比如说我写了一个发送消息的方法。比如说有一个参数是 messageDTO,但是他有很多属性,比如说 topic,tag,shadingKey,msg, delayTime 等等,但是我希望别人在使用这个方法的时候传入 messageDTO 是我想要的,即我会将无参构造方法私有化,因为我不想让别人使用无参构造new一个对象出来,(因为自己去set可能某一些参数设置有遗漏),然后只限制了 几种构造函数,或者使用静态方法来创建对象。
然后对象的入参是由要求的。比如说你想法 普通消息,那么需要 topic和msg,发延迟消息,需要topic msg和delayTime,发顺序消息需要额外再加一个shadingKey,请问在这种情况下如何使用建造者模式。即只允许使用某一组参数来创建对象

二、探索

每种设计模式(甚至任何技术)都有自己适合的场景。
虽然我们学了建造者模式,未必一定要用建造者模式。

针对这种场景,有很多方法可以更优雅地实现:

  • 可以使用工厂模式,通过函数名体现类型。
  • 可以通过继承的方式通过类名来体现类型。
  • Builder 模式变通。

2.1 静态工厂

MessageFactory类
构造普通消息

public static MessageDTO buildCommonMsg(String topic, String msg) {

// 直接 new 然后 set 或者用 builder都可以
}

构造延时消息

 public  static MessageDTO buildDelayMsg(String topic, String msg,Long delayTime) {
// 省略
 }

顺序消息类似

 public static MessageDTO buildOrderedMsg(String topic, String msg, String shadingKey) 
{
    // 省略
 }

可以加上参数校验。

2.2 利用继承来表意

普通消息 CommonMsgDTO

public class CommonMsgDTO{
  private String topic;
  private String msg;

   // 提供全参构造方法
}

延时消息 DelayMsg

public class DelayMsgDTO extends CommonMsgDTO{
  private Long delayTime;

   // 提供全参构造方法
}

顺序消息 DelayMsg

public class OrderedMsgDTO extends CommonMsgDTO{
  private String shadingKey;

   // 提供全参构造方法
}

这样构造时只有全参数构造函数,就不容易传错,而且看名知意。
如果传 null 可以报错。


2.3 builder模式活用

public static class Builder{  
 // 省略
 public Builder(String topic, String msg){
   // 省略
 }
   // 其他属性的set 方法
}  

对普通的 builder 模式稍微改造下,将必备参数作为 Builder 的唯一构造函数的参数。
这样必备属性必然会传入。
但是如果必传参数太多,不推荐使用这种方式。


哪怕是不同的 builder 模式,在 build时进行参数校验。

可能还有很多解决方案,上面给出两个比较简单且常见的方法。
在执行发送消息的函数上加上参数校验,这样就不容易出错。

三、总结

希望大家一定要破除 ”手里拿着锤子,看啥都像钉子“的心理。
在学习任何技术时,思考其最适合的场景,为了解决什么问题,局限是什么。

在解决问题前想清楚问题是什么?

比如这位同学核心是为了能让使用者清晰地区分类型,然后让使用者知道不同类型的参数差异。
然后再去思考怎样更容易区分开呢?必传参数一定要早构造的时候校验吗?
慢慢地,问题就明了了,就更容易得到更科学的答案。

总之,既要埋头苦学,又要抬头看路。学而不思则罔!


如果想在开发中少趟坑,感兴趣可以看看我最近出的几个 GitChat:

相关文章
|
开发框架 安全 .NET
分享119个ASP整站程序源码,总有一款适合您
分享119个ASP整站程序源码,总有一款适合您
357 4
|
Java C#
C#学习系列相关之多线程(五)----线程池ThreadPool用法
C#学习系列相关之多线程(五)----线程池ThreadPool用法
697 0
|
10月前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
268 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
10月前
|
安全 数据挖掘 BI
代理商级差制分销系统模式开发技术规则
代理商级差制分销系统开发技术规则涵盖系统架构设计、用户角色与权限管理、佣金结算、数据分析、商品分类、激励机制及合规性、技术实现与优化等方面,旨在构建稳定、安全、高效的分销平台,满足多层次代理商管理需求,提升用户体验。
|
并行计算 PyTorch Linux
【Deepin 20系统】Linux系统安装Pytorch、Torch
本文提供了在Deepin 20系统中安装PyTorch及其相关库的指南,包括创建conda环境、安装PyTorch及依赖库的步骤。
186 3
|
运维 监控 安全
DevOps实践:从理论到企业级应用的转化之路
【7月更文挑战第21天】在数字化转型的大潮中,DevOps作为一种提升软件开发与运维效率的方法论,正逐步成为企业IT战略的核心。本文将从DevOps的基本概念出发,深入探讨其在企业级应用中的实践路径,包括文化理念转变、工具链的选择与集成、持续交付的实施步骤以及监控与反馈机制的建立。通过分析成功案例,旨在为读者提供一条清晰的DevOps转型路线图,帮助技术团队和运维人员理解并实施DevOps,以实现快速迭代和高效运营的目标。
|
Linux
Linux Resin开机自动启动脚本写法
在Linux中,可以通过systemd服务来实现开机自动启动脚本。下面是一个编写开机自动启动脚本的示例:
479 0
|
编译器
unsigned long int 和 unsigned long一样吗?
unsigned 代表的是无符号的整形数
492 0
|
JavaScript 前端开发 CDN
使用jQuery Validate进行表单验证详解
使用jQuery Validate进行表单验证详解
|
机器学习/深度学习 存储 算法
【数据结构入门精讲 | 第十二篇】考研408、公司面试树专项练习(一)
【数据结构入门精讲 | 第十二篇】考研408、公司面试树专项练习(一)
689 0