只接受发布货源信息,不可发布违法信息,一旦发现永久封号,欢迎向我们举报!
1064879863
16货源网 > 餐饮行业新闻资讯 > 软件开发 >  什么是软件开发中的过度设计?


什么是软件开发中的过度设计?

发布时间:2019-05-18 15:12:37  来源:网友自行发布(如侵权请联系本站立刻删除)  浏览:   【】【】【
耗费了无用的脑力或者资源,没有实际转化为更良好的产品
什么是软件开发中的过度设计?耗费了无用的脑力或者资源,没有实际转化为更良好的产品为了设计而设计,过度最求模块化,可扩展性,设计模式等。满足当前的现实需求是最基本的原则,也是一切设计的出发点。想多了一般被认为‘过度设计’ 的系统 都是设计的不好。
设计,抽象不是坏事,但是抽象合理的系统必定是容易理解的,让复杂度下降的
而设计的不好的系统,会导致复杂度上升,这就被认为是‘过度设计’了下面这几种吧:from 6个变态的C语言Hello World程序。
当然了,如果诚如文中所说,为了混淆,这就不算过度设计。否则就不仅仅是过度设计了,而是Drunbility

hello1.c


 #define _________ }
    #define ________ putchar
    #define _______ main
    #define _(a) ________(a);
    #define ______ _______(){
    #define __ ______ _(0x48)_(0x65)_(0x6C)_(0x6C)
    #define ___ _(0x6F)_(0x2C)_(0x20)_(0x77)_(0x6F)
    #define ____ _(0x72)_(0x6C)_(0x64)_(0x21)
    #define _____ __ ___ ____ _________
    #include

_____

hello2.c

    #include
    main(){
      int x=0,y[14],*z=&y;*(z++)=0x48;*(z++)=y[x++]+0x1D;
      *(z++)=y[x++]+0x07;*(z++)=y[x++]+0x00;*(z++)=y[x++]+0x03;
      *(z++)=y[x++]-0x43;*(z++)=y[x++]-0x0C;*(z++)=y[x++]+0x57;
      *(z++)=y[x++]-0x08;*(z++)=y[x++]+0x03;*(z++)=y[x++]-0x06;
      *(z++)=y[x++]-0x08;*(z++)=y[x++]-0x43;*(z++)=y[x]-0x21;
      x=*(--z);while(y[x]!=NULL)putchar(y[x++]);
    }

hello3.c

    #include
    #define __(a) goto a;
    #define ___(a) putchar(a);
    #define _(a,b) ___(a) __(b);
    main()
    { _:__(t)a:_('r',g)b:_('$',p)
      c:_('l',f)d:_(' ',s)e:_('a',s)
      f:_('o',q)g:_('l',h)h:_('d',n)
      i:_('e',w)j:_('e',x)k:_('n',z)
      l:_('H',l)m:_('X',i)n:_('!',k)
      o:_('z',q)p:_('q',b)q:_(',',d)
      r:_('i',l)s:_('w',v)t:_('H',j)
      u:_('a',a)v:_('o',a)w:_(')',k)
      x:_('l',c)y:_('t',g)z:___(0x0)}

hello4.c

    int n[]={0x48,
    0x65,0x6C,0x6C,
    0x6F,0x2C,0x20,
    0x77,0x6F,0x72,
    0x6C,0x64,0x21,
    0x0A,0x00},*m=n;
    main(n){putchar
    (*m)!='0'?main
    (m++):exit(n++);}

hello5.c

    main(){int i,n[]={(((1<<1)<<(1<<1)<<(1<<
    1)<<(1<<(1>>1)))+((1<<1)<<(1<<1))), (((1
    <<1)<<(1<<1)<<(1<<1)<<(1<<1))-((1<<1)<<(
    1<<1)<<(1<<1))+((1<<1)<<(1<<(1>>1)))+ (1
    <<(1>>1))),(((1<<1)<<(1<<1)<<(1<<1)<< (1
    <<1))-((1<<1)<<(1<<1)<<(1<<(1>>1)))- ((1
    <<1)<<(1<<(1>>1)))),(((1<<1)<<(1<<1)<<(1
    <<1)<<(1<<1))-((1<<1)<<(1<<1)<<(1<<(1>>1
    )))-((1<<1)<<(1<<(1>>1)))),(((1<<1)<< (1
    <<1)<<(1<<1)<<(1<<1))-((1<<1)<<(1<<1)<<(
    1<<(1>>1)))-(1<<(1>>1))),(((1<<1)<<(1<<1
    )<<(1<<1))+((1<<1)<<(1<<1)<<(1<<(1>>1)))
    -((1<<1)<<(1<<(1>>1)))),((1<<1)<< (1<<1)
    <<(1<<1)),(((1<<1)<<(1<<1)<<(1<<1)<<(1<<
    1))-((1<<1)<<(1<<1))-(1<<(1>>1))),(((1<<
    1)<<(1<<1)<<(1<<1)<<(1<<1))-((1<<1)<< (1
    <<1)<<(1<<(1>>1)))-(1<<(1>>1))), (((1<<1
    )<<(1<<1)<<(1<<1)<<(1<<1))- ((1<<1)<< (1
    <<1)<<(1<<(1>>1)))+(1<<1)), (((1<<1)<< (
    1<<1)<<(1<<1)<< (1<<1))-((1<<1)<< (1<<1)
    <<(1<<(1>>1)))-((1<<1) <<(1<< (1>>1)))),
    (((1<<1)<< (1<<1)<<(1<<1)<< (1<<1))- ((1
    <<1)<<(1<<1)<<(1<<1))+((1<<1)<< (1<<(1>>
    1)))), (((1<<1)<<(1<<1) <<(1<<1))+(1<<(1
    >>1))),(((1<<1)<<(1<<1))+((1<<1)<< (1<<(
    1>>1))) + (1<< (1>>1)))}; for(i=(1>>1);i
    <(((1<<1) <<(1<<1))+((1 <<1)<< (1<<(1>>1
    ))) + (1<<1)); i++) printf("%c",n[i]); }

hello6.cpp

下面的程序只能由C++的编译器编译(比如:g++)

    #include 
    #define _(_) putchar(_);
    int main(void){int i = 0;_(
    ++++++++++++++++++++++++++++
    ++++++++++++++++++++++++++++
    ++++++++++++++++++++++++++++
    ++++++++++++++++++++++++++++
    ++++++++++++++++++++++++++++
    ++++i)_(++++++++++++++++++++
    ++++++++++++++++++++++++++++
    ++++++++++i)_(++++++++++++++
    i)_(--++i)_(++++++i)_(------
    ----------------------------
    ----------------------------
    ----------------------------
    ----------------------------
    ----------------i)_(--------
    ----------------i)_(++++++++
    ++++++++++++++++++++++++++++
    ++++++++++++++++++++++++++++
    ++++++++++++++++++++++++++++
    ++++++++++++++++++++++++++++
    ++++++++++++++++++++++++++++
    ++++++++++++++++++++++++++i)
    _(----------------i)_(++++++
    i)_(------------i)_(--------
    --------i)_(----------------
    ----------------------------
    ----------------------------
    ----------------------------
    ----------------------------
    ------i)_(------------------
    ----------------------------
    i)return i;}

来个形象点的故事........

-----------请大家相信我,这个真的是来自天才小熊猫的新浪微博。补充下:楼上高分答案谈的是“功能上的过度设计”,可以理解为发生在产品经理身上的问题。
而我谈的是“程序上的过度设计”,是发生在程序员身上的问题。
这两者基本上是两个方面的问题,诸位看官看前务必心理有数 :-)

===================================================

顶楼童鞋举的例子很精彩,不过过于极端了,实际上的过度设计往往发生得隐蔽和普遍得多。

简单来说,过度设计就是进行了过多的面向未来的设计,进行了不必要的抽象封装,为系统增加了不必要的复杂度。
举个例子,你要做一个功能模块,但你考虑到到这个系统里还有几个未完成的模块和你要做的东西类似,所以你决定为此额外做一些抽象和封装,以便将来复用。然而到后来你开发那些相似的模块时你才发现,可能是由于抽象不足或抽象错误,你不得不重新修改之前的封装才能完成复用,导致最终成本实际上还不如不做;或者你发现复用的部分所降低的成本实际上还不如包装花费的成本。 这些都是最常见的过度设计的例子。
程序员在掌握了一些基本的设计能力之后,最常见也是最难克服的设计问题往往就是过度设计。上面的错误我相信大多数人都一而再,再而三的的犯过。

与过度设计相对的就是设计不足。
虽然是两个相对的概念,但设计不足和过度设计绝大多数时候都是一起出现的。都是最常见的设计问题。设计不足不仅常见于新手,老手也常犯。甚至我还见过有一类老程序员在经历过多次过度设计的打击之后,转向另一个极端,否定抽象封装的作用,走上“反设计”的道路。

过度设计和设计不足的平衡问题没有很好的解决办法,只有依靠经验的积累和不断的总结思考。如何把握这个度是最能考验程序员的经验和价值的问题之一。

我所尝试过的软件方法中,有一种方法的思维方式对于解决这个问题帮助最大,就是TDD(测试驱动开发),这里简单说下为什么TDD能解决这个问题:
TDD的一个核心思想是小步增量,不断重构。具体说来就是TDD有两个状态(常见的说法是两顶帽子):
状态A:用test case描绘需求,并使用最简单的方式满足这个test case。注意要用最简单的方式满足这个需求,不能为任何test case之外的需求做任何设计。 test case通过之后进入状态B;
状态B:重构代码,让现有的代码在尽量保持简单性的同时足够优雅清晰。注意此时你只能对现有的实现代码进行重构,不能增加任何新的功能和test case。
整个TDD的过程就是在这两个状态间不断转换的过程。在状态A增加功能,在状态B优化设计。

TDD的这种思维方式走的稍微极端一点。它直接排斥任何对未来的设计,转而以优雅简洁的设计和test case来为未来需求的重构降低成本。 可以说严格遵循TDD做出来的设计必然在过度设计和设计不足方面都不会有太大的问题。

我严重推荐TDD。不管你最终会不会接受TDD这种开发方式,它独特的思维方式都必然会给你的设计观念带来很大影响。多想三步的可能性,但只多做一步的设计,基本就可以了

多想三步,就要多做三步,就是过度设计,因为越面向未来的设计,越没有依据,你还没做完,产品改需求了

只要team里面的人没有牛逼到来什么需求都可以吧代码重构到恰好满足那个需求的最佳状态,那么我们在开发的时候总是要考虑一下未来的需求到底会往哪个方向走。


你蒙中了,就叫正交分解。

你没蒙中,就叫过度设计。

前面票数最高的 @柯鼠 的答案虽然很搞笑,但是其实不准确,它混淆了程序设计和产品设计的概念。图中的软件虽然最后变得十分诡异,但其实每一个新版本都忠实地实现了新的需求。变得诡异的是需求,而不是程序设计。

程序设计的一切都应该以需求为准。程序的过度设计,并不是你实现了太多的功能,而是为了实现太多你觉得会出现结果没有出现的需求,导致系统架构过于庞大复杂。所以通常一个程序是否被过度设计,看界面是看不出来的。。。


过度设计这个东西就是想太多,希望你的程序能应对一切需求的变化,希望你的程序拥有一切牛掰的特性,但实际上你水平就在这里所以你做不到。一旦你想做的超出了你的水平,你很可能把自己绊住,根本实现不出来;或者实现出来太过复杂导致bug多多效率低下;或设计歪了,你发现意料之外的需求根本都加不进去了!

那么对于一个经验不足的程序员,怎么意识到这是过度设计呢?
没办法,设计是否合适,这很大程度上就一个靠主观判断的事,没有经验就没法分辨,必须多写多看多思考。失败是成功的麻麻,只要想做出合适的设计,不当的设计就是必经之路。你想的经常不会发生,发生的总能刷新你的世界观。不每天来刷刷经验,怎么能更好地认识世界呢_(:3」∠)_大牛们其实就是刷出来的,哪些需要哪些不需要,哪些做完了维护成本可能会比修改成本还要高,怎么做效率更高,怎么做可以降低耦合度。。。当然,就算世界观圆润的大牛们也会失足的(?)′?`(ヾ)

虽然没法完全避免过度设计,但下面几个建议,也许能帮上忙:
1. 一定记住设计是为了满足需求,不要为了设计而设计;
2. 不要花费太多精力在你觉得一年之内不会提出来的需求上;
3. 如果一个实现能比较容易的改成另一个实现,现在选择容易的一方;
4. 去掉这个中间层会发生什么?
5. 不要花太多时间在设计上,人人都超不出自己的界限;
6. 不要指望一下把所有细节都设计出来,边写边重构是个好习惯;

其实当你完成一个系统之前都认识不到自己是否有过度设计,而当你认识到自己有过度设计的时候正说明了你在成长。一个设计用一段时间你就知道哪里有问题了,有条件的话过一段时间就把以前写的翻出来重构一下,每半年一年你可能都会有新的想法。

过度设计就是鸭子还没打下来,就在争论怎么吃的问题。

软件的设计,目的是满足需求,这个需求是多维度的综合: 业务要求,性能,可靠性,安全……等等。过度设计,就是在某个或者多个维度上超出实际需求的裕度。好比一个网站预计百来人访问,你给个能支撑500人的设计就够了,结果设计出一个百万访问量的架构来。
实际当中,要避免过度设计,我觉得主要是两点:
1. 弄清楚需求,不要臆想,在其基础上适当放宽。
2. 要有成本概念,在工程上,超过需求到一定程度的设计极大概率会有超额成本。
另外不太同意对未来预测进行设计。因为对需求的预测和对股价预测一样不靠谱,就算你在某个维度猜中了,其它维度上的变化可以让你的设计面目全非。

一个经验不足的程序员如果太过关注设计,极有可能导致设计过度。因为经验不足,所以很难理解抽象层次,也就无法正确设计,很多时候只是在绕圈子。

一个简单的例子:XML解析有两种方法,SAX和DOM,而DOM实际上是基于SAX实现的,不理解本质的程序员有可能为了某些特殊需求将DOM包裹了一层,出来的却是个SAX解析器。所以新手更容易犯的是错误的设计,这和过度设计是有一些差别的。

真正的过度设计容易出现在规模较大的项目,规模大,所以人员多,如果不尽可能预先设计,容易造成返工,浪费资源。设计的适度依赖于架构师的经验和需求的稳定性,实际上也很难避免过度的设计。

对于一两个开发的小项目,谈论过度设计则有点奇怪,因为在这种情况下导出好设计的唯一手段就是重构。新手想要不经过反复修改,而一次性解决问题,实际上是在给自己找麻烦。

即使大规模的项目,如果能够在前期控制参与人员,在小范围内实现核心功能,并通过重构改良设计,然后再增加人员进行全面开发,也会是一个很好的实践!感觉前面一些关于 “界面功能过于复杂甚至于混乱” 的例子并不是题主所关注的过度设计。题主所问的应该是程序开发中的过度设计。

“过度设计”这个词在日常使用中其实是个模糊,主观的概念:基本上就是表达说话人认为,这个设计中某个东西其实没有必要做或者不需要在当前版本做。为什么说是主观,因为“过度设计”这类评语通常是在设计审查阶段提出的。而事实是在系统实际上线并稳定运行一段长时间之前,根本无法客观地确定什么是“适度设计”。

说起“过度设计”时,不少人会认为“适度设计”就是以最快的开发效率和最优的运行效率实现目前已知的所有需求。但这显然不对,否则任何人只要能认字(读需求文档),会编程就能做出最合适的设计决定,还要架构师来干什么,程序设计也不会发展成今天的样子(至少面向对象就没必要出来了)。现实中在产品交付前需求是可能会变动的(可参考 @柯鼠 的例子,如果是持续服务型的产品,交付后的需求变动也需要考虑),而且开发过程中人员也可能发生变动。那么总体来说,最优的设计应该把最可能发生的需求变动和人员变动考虑在内:
对付需求变动(所谓代码灵活)至少需要做到代码不重复(单点改动),高聚合(细分功能代码,提倡小对象,短方法),低耦合(隔离变动);对付人员变动则至少需要做到代码易读,符合思维习惯。

在大部分情况下,灵活 - 易读 - 效率 三者是一组 Trade-off (实在想不起中文表达是啥……)。更灵活,意味着更精细的功能分解和更抽象的概念(以便复用)。功能细分会影响局部开发效率(需要码更多的字)和整体运行效率(接口调用和传参增多),概念抽象影响易读性(原则上每引入一个新的概念都会增加阅读负担)。同理,追求易读也会一定程度上影响开发效率(码更多的字)。最后问题归结于:如何找到平衡点。

更大的问题是,这些变动都是”可能发生“,在设计期没人能确定事实上到底会不会发生,会在哪个部位发生。如果以”实践是检验真理的唯一标准“来看,最后证实蒙对了的,就是适度设计,蒙错了,就是过度设计,但这种马后炮对于新手在设计期的判断没有任何帮助。在现实中,唯一的依靠就是经验 —— 资深程序员经过无数次”考虑不周“和”过度设计“的教训,培养出来的什么地方应该未雨绸缪的直觉 (或者按马丁福勒的说法:代码的气味)。

因此,当你听到有人说”这里是过度设计“时,可能的情况是:
1. 说话人根据他自身经验,判断出目前不必要考虑这里的未来变动,且如果考虑会大大增加工作量,或会显著影响效率,或引入的概念难以理解而可能影响团队合作
2. 说话人无法判断是否需要考虑这里的未来变动,但他认为如果考虑会增加额外的工作量,影响效率,或他觉得你的设计难以理解。

如果是1,则他的判断有助于让设计趋向于”合适设计“。如果是2,则他也是在蒙。而且,如果你对他的经验和能力不充分了解,也无法确认事实上是哪种情况。

所以,总而言之,在现实中你听到”过度设计“一类的评语,如果说话者不是你在技术上特别佩服的人或者你的顶头上司,基本可以忽略(他认为是过度而已,反过来说你也可以认为他考虑不周),最多可以当一个提醒,复查一下设计。

==================================
第二个问题:如何避免过度设计
既然在设计期无法准确定义”合适设计“,自然也无法准确定义“过度设计”,因此也不会有一套明确按部就班的方法去避免过度设计。但有一些指导原则可以有助于让你的设计趋向合适设计:

1. 对自己参与过,并经过实践证实”考虑不周“和”过度设计“的案例多做总结。特别应该注意,不要出现几次了过度设计的失误,就完全走向反面,不做任何设计。
2. 多请教有经验的程序员或架构师
3. 不论多简单的项目,先做设计,再开工 (避免走向过度设计的反面)
4. 理解各种经典的设计模式。你可以在充分理解后判断在某种情况下使用某种模式是过度设计,即使判断错误也不要紧,有下面几点补救。但不建议在感觉难以理解的前提下认为所有使用这种模式的企图都是过度设计。
5. 在没有任何经验可以借鉴的情况下,不确定是否必要且工作量大或不易理解的灵活性设计一律砍掉,工作量小且不需引入新概念的灵活性设计尽量保留。
6. 不要容忍已经出现的重复代码,发现重复代码随时通过重构技巧改为单点
7. 在编写新代码过程中尽可能把旧代码中的“臭味”部分重构掉
8. 尽可能保证较高(我现在公司的标准是85%以上)的单元测试覆盖率,保证重构的效率。但对于一些小型项目或者本来就没有单元测试的遗留项目,有时 “高单元测试覆盖率” 本身就被认为是”过度设计“,要看管理层的理解了。

======================================
最后说一下重构

重构是解决“过度设计”的过渡方案,有助于度过从初级程序员到资深程序员之间青黄不接的阶段,当积累了足够经验,才有可能一次性作出准确的设计判断。而保证你敢去重构的基础是单元测试覆盖率(否则你在重构时手指抽筋引入了一个bug会被骂死)。此外,高单元测试覆盖率特别是高分支覆盖率(Branch Coverage)又能反过来鼓励你进行更好的设计(尽量细分功能单元便于编写测试,消除重复代码避免重复测试,等等),能形成一个良性循环。TDD我还没有真正实践过,就不在这里讨论了。软件开发中的过度设计: "想得太远".
UI中的过度设计: 刻意体现某种"主义".杀毒软件的游戏加速,聊天软件的在线支付。数据库的可移植性

当年可是接受过很多教育的...
  • 采用Hibernate的好处之一就是,HQL可以帮我们确保将来的不同数据库之间移植性。
  • 为什么不能写存储过程?一个重要的原因就是业务逻辑放到数据库里会导致数据库移植成本变大。
  • 程序内尽量采用标准SQL语法,因为我们要考虑将来的移植风险。

可是老子干了这么多年,从来没有碰到一个需要做数据库移植的项目哪!

多一点点就行。

不得不说下汇丰网上银行。

我有一张大陆的汇丰卡和一张香港汇丰卡,它们对应的网上银行服务,是独立的两个账户。未来我如果有了其他的境外账户,每个境外账户都会有一个单独的网上账户。这个问题姑且认为合理,各地金融政策不同,有割裂的账户也是可以理解的。

在汇丰中国的账号和密码体系是:

  1. 一张银行卡卡片,里面包含三个账户:
  • 人民币账户;
  • 港币现汇账户;
  • 港币现钞账户;

上面的三个账户分别有三个账户号,加上银行卡的卡号,一共是4个号码;

另外还有一个网上银行的用户名,好处是登录这一个网银用户名,可以统一管理上面的三个账户,暂时也还算OK吧。

2. 密码包括:

  • 银行卡密码,用于在ATM机取款和查询操作,一个密码可以从三个账户取钱,合理;
  • 网上银行的登录密码,首次登录后,iPhone可以启动指纹登录;
  • 安全密码器:下图这个东西,没错,9102年了,我出门在外如果需要使用汇丰银行,还得随身带着这个东西。然后,为了不让其他人捡到这个安全密码器就能用,安全密码器,自己也有一个密码。(这里我就不说激活这个安全密码器需要什么步骤了)
汇丰银行的安全密码器

如果要从汇丰大陆账户往外转账,需要经过以下验证:

  1. 再次输入网上银行的登录密码;
  2. 输入银行卡的取款密码;
  3. 获取本次转账的短信验证码,并正确输入;
  4. 输入安全密码器(上图那个东西)提示的密码,为了获得这个密码,我还需要输入安全密码器的密码。

汇丰网上银行一直强调安全,上面的流程安全么,确实安全,安全到我自己都差点没法用我自己的钱了……总之体验了一次转账服务后,我就轻易不想把钱往汇丰银行里转了呵呵呵呵呵呵呵…

如果是为了安全,有没有其他的解决方案?我不是互联网金融圈的人,如果有了解的同学看到这儿,可以帮忙解答一下~


还没完,接下来是

汇丰香港的网上银行服务:

账户:

  • 一张银行卡、一个账户号,香港卡比大陆卡好一点的是,卡号就是账户号,不用记两个了;
  • 一个登录网上银行的用户名,这个用户名和大陆汇丰网银的用户名是分开的,是两个用户名;

密码:

汇丰香港的网银密码体系是我见过最最最最最最最变态的密码没有之一:

  • 银行卡密码;
  • 网银提示问题答案:这可不是用来找回密码时的提示答案哦,就是网银的登录密码;
  • 网银密码(第二个密码);
  • 流动保安编码:类似上面提到的安全密码器,不过这个不需要随时揣一个硬件,在手机上装一个APP就好了,首次激活这个流动保安编码,需要一个编码,激活的细节就不在这里说了。另外这个流动保安编码的APP,也需要一个登陆密码……不知道各位看晕了么,反正我用着挺晕的。

由于光汇丰银行的账户我就有两个,每个账户还有多个密码,多个密码不允许相同,都还必须是英文字符+数字+符号的复杂密码,不允许包含可背诵的连续的数字和字符(12345,abcde之类),不允许包含键盘上连续的数字和字符(qwert,zxcvb之类),于是我干了一件非常愚蠢也非常危险的事情:把这些密码老老实实写在了笔记中,把它收藏了起来……作为一个产品狗,这让我感到无比的羞耻

至此我终于完成了汇丰香港网上账户的注册,OK我们来看一下如何登陆:

首先输入用户名:

点击“继续”:

重点来了,这个页面需要输入两个密码:

  • 输入提示答案;
  • 输入密码的随机三位,随机三位!随机三位!

比如这一次让我输入了第一、四、五位,下一次会让我输入第二、三、六位,再下一次可能是一、四、八位。

看到这里我彻底疯了啊啊啊啊啊啊!难道我要把这个密码倒背如流?为了准确输入这几位,我又做了另一件非常蠢的事情:每次登陆时,把密码用纸笔写下来,或者用txt敲出来,手指头数着第几位是什么字符

我不知道上面的设计,是否真的实现了安全的目的。对银行来说应该挺安全的,毕竟这难用程度,连用户本人都常常无法登陆,被冒用登陆的可能性应该也降低了很多。

但由于这个过度的设计,导致用户不得不借助一系列的外部辅助手段才能使用它,而这些辅助手段,在我看来风险极高,一系列的密码都存在一份收藏夹里,每次登陆我都需要在一个地方留下我的密码,而这些痕迹很难完全销毁或彻底删除。我不知道汇丰银行在设计这套流程的时候是否考虑了这一点,但我想,即便是由于这些原因导致了信息泄露,责任也不在汇丰银行,因此并不care吧。


本人是经济学专业,经济学里定义的“优质”的含义:哪怕是为了保障安全、为了提高质量,也不应该做无止境的投入,当边际成本上升到与边际收益相等的时候,就应该停止了。

如果说前面的N个相互独立的帐号和卡号还能理解,这个多重密码的设计完全就是反人类了。一味追求流程内的安全,逼迫用户不得不使用这套流程之外的手段来辅助,造成了极大的负外部性,而这负外部性的成本由谁来承担呢?最终还是用户。

以上,是我理解的过度设计。

题外话:这么难用,我为什么还要成为汇丰银行的用户呢?因为汇丰提供的跨境金融服务牛逼啊,网银只是它提供的服务的一小部分,而除了汇丰银行之外我并没有其他更好的选择(苦笑)。与之前拿着大陆银联卡去香港交保费的惨痛经历相比,我还是更愿意在汇丰的网上银行多折腾一下。所以啊,产品狗们,你的产品有没有“无论再难用也赶不走用户”的核心竞争力啊?(摊手)

责任编辑:
热门阅读排行
© 16货源网 1064879863