今天看啥  ›  专栏  ›  冷风在北京

基金要这样买才赚钱

冷风在北京  · 掘金  ·  · 2021-01-31 22:16
阅读 86

基金要这样买才赚钱

大家好啊,我是冷风,今天我们来说说买基金的事儿。

0 . 前言

前几天,大盘涨的有点猛,一度冲上了 3600 点大关,好多新鲜的韭菜们都摩拳擦掌,撸起袖子,准备入市了。 不料入市后发现,大盘又开始“打折大促销”了,以前是满 3400 减 200,现在是满 3600 减 200,又回到了 3400 点。

还是熟悉的配方,还是原来的套路。

大盘的走势,基金的行情我们没法去预测,有可能会亏钱。那么,如果在基金的手续费上能省一点,那也相当于赚钱了呀。

一般来讲,不同的代销机构,手续费差异还是挺大的。像天天基金的手续费通常在基金公司的管理费基础上打一折,只需要 0.1% 至 0.15% ,而银行类代销机构大多数情况下不打折,一般需要 1.2% - 1.5% ,差了不少。

天天基金费率 ▲
天天基金费率 ▲
宇宙行费率 ▲
宇宙行费率 ▲

假设买 10w 基金的话,按照管理费 1% 来计算,光手续费就差了 900 多。

今天我们借买基金的这个费率计算,说说访问者(Visitor)设计模式。

1 . 访问者模式

我们都知道,基金公司的基金,会在很多销售机构上去卖。比如银行,互联网代销平台、第三方销售公司等等。不同的销售机构会有不同的费率折扣,或者优惠手段。有的机构有打折,有的机构有满减,总之是每个销售机构都有一个复杂的费率计算方法。

假设现在让你设计一个系统,来同时实现各个代销机构的费率计算,你会怎么做?

最容易想到的方法肯定是 if , else 啦。

  if(代销机构.equals("某银行")){
    不打折;
  }else if(代销机构.equals("天天")){
    一折费率;
  }else if(代销机构.equals("支付宝")){
    满减优惠;
  }

复制代码

很显然,这种写法是有很大问题的,因为大多数情况下,代销机构或者费率算法肯定会变化的,变化时,一定是要改主体代码的。另外还有一个问题,就是这样做会导致主体结构不够清晰。

那有没有更好的办法呢?

这时,可以考虑使用访问者模式。

访问者模式,就是别人来访问你,给你带点东西。这里边有三要素:你(被访问者),别人(访问者),东西(具体行为或算法)。

先看下访问者模式的大概定义:

访问者模式:在结构不变的情况下,动态地改变其内部的行为。

来仔细分析一下,结构不变,动态改变内部行为,那这个行为,一定是需要访问者去定义和传递的。

我们先看下类图。

从图中可以看出,Visitor 模式的三要素:

  • 接收者 Accepter
  • 抽象访问者 abstract Visitor
  • 具体访问者 Visitor

逻辑上,接收者中的 accept 方法,调用 vistor 中的 visite 方法。也就是说,接收者的动作是由访问者来定义的。

回到上面的例子,我们看下具体怎么做。

Fund.java (接收者)

public class Fund {
 private double fee = 1;
 //初始手续费
 double getOrignalFee(){
  return fee;
 }
 public double getFee(SellingAgent sa){//代销机构手续费
  return sa.visite(this);
 }
}
复制代码

Fund 作为主类(接收者),提供了获取基金费率的 getFee 方法,这里传入了 SellingAgent 对象。方法实现上,调用了访问者的 visite 方法,并且将主类对象传过去。

SellingAgent.java (抽象访问者)

abstract class SellingAgent{
 abstract double visite(Fund fund);
}
复制代码

定义了抽象访问者,所有的访问者去继承并实现 visite 方法。

ICBC.java (具体访问者)

class ICBC extends SellingAgent{
 @Override
 double visite(Fund fund) {
  return fund.getOrignalFee() * 1;
 }
}
复制代码

tiantianFund.java(具体访问者)

class tiantianFund extends SellingAgent{
 @Override
 double visite(Fund fund) {
  return fund.getOrignalFee() * 0.1;
 }
}

复制代码

定义了 2 个具体访问者,ICBC 和 tiantianFund ,并实现了 visite 方法。在方法中,访问者定义了具体的内部行为。这里,ICBC 的行为是 “不打折”,tiantianFund 的行为是 “打一折”。

FundClient.java (调用方)

public class FundClient {
 public static void main(String[] args) {
  //SellingAgent sa = new ICBC();//结果 0.1
  SellingAgent sa = new tiantianFund();//运行结果 1
  System.out.println(new Fund().getFee(sa));
 }
}

复制代码

小结一下: 在这个设计上,我们定义了一个接收者 Fund,作为核心逻辑,而这个结构是不变的。针对不同的代销机构,定义不同的 visitor 去实现不同的费率逻辑。

访问者模式的好处是,将主体的逻辑结构和数据算法分离开来了,方便扩展逻辑。

访问者模式的缺点在于,假设接收者结构发生改变(例如增加其他方法,或者增加其他兄弟接收者),所有的访问者都需要随之变化。

2 . 访问者模式和策略模式的区别

有人说,访问者模式看起来有点像策略模式。其实仔细分析,是有区别的。

策略模式侧重于主体机构的变化,而访问者模式更强调主体结构不变,变化的是传入的访问者。

相同点是,本质上来讲,都是面向接口的编程。

3 . 访问者模式的经典应用场景

在经典设计模式书籍 《设计模式-可复用面向对象软件的基础》 中,GOF(Gang of Four)提到了这样一种使用场景:编译器编译时对于抽象语法树的分析。

抽象语法树中,每个节点都需要类型检查,如果将检查规则放在检查的代码里,会很不方便,而且还有可能修改。此时,可以使用vistor模式,传入 Vistor ,将规则写在 Vistor 里。

4 . 总结

稍微总结一下,今天我们讲了设计模式中的访问者(Visitor)模式。 访问者模式能够在主体结构不变的情况下,动态地改变内部行为,而这个内部行为,是由访问者来定义的。访问者模式分离了类的逻辑结构和具体实现。 访问者模式的三要素,分别是接收者,抽象访问者,具体访问者。 访问者模式和策略模式的区别在于,策略模式侧重根据不同的情况,动态地改变内部行为;而访问者模式则更强调,内部结构不变,由访问者去定义具体的行为。

访问者模式的经典应用场景在编译器上,编译器要对代码进行校验,而这些校验规则就是 Visitor 去实现的。 此外,也包括 ASM 生成动态代理,也用到了很多 Visitor 模式。

好了,本次分享就到这里,下次见。

对了,下次再买基金,要关注下代销机构的费率,一般推荐天天基金。




原文地址:访问原文地址
快照地址: 访问文章快照