乐趣区

关于程序员:手里拿着锤子看啥都像钉子

工具与资源核心
帮忙开发者更加高效的工作,提供围绕开发者全生命周期的工具与资源
https://developer.aliyun.com/…

一、背景

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

老师,提一个问题,在理论生存中遇到的 比如说我写了一个发送音讯的办法。比如说有一个参数是 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 时进行参数校验。

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

三、总结

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

在解决问题前想分明问题是什么?

比方这位同学外围是为了能让使用者清晰地区分类型,而后让使用者晓得不同类型的参数差别。
而后再去思考怎么更容易辨别开呢?必传参数肯定要早结构的时候校验吗?
缓缓地,问题就明了了,就更容易失去更迷信的答案。

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

退出移动版