解惑

解己之惑,解人之惑

2007年4月 (第4页共4页)

装修停工

昨天说了脱排和煤气灶的事情,越想越不对,昨天觉也没有睡好,然后老婆在上班的路上提前一站下车,因为她看到一个卖木材的点,进去随便看了下,发现他们给我们做厨柜和衣柜的材料竟然是最便宜的那种双面白高密板,80块钱一块,老婆就赶紧给我打电话,我和岳父商量了下就请假到房子那边去了,那边还在做彩铝的窗子,看了下,很薄的,好像也不太结实,彻底的心寒了,赶紧打电话,和那个老板约好到他的公司谈一下,赶到那个老板的公司一看,彻底无语,就是上海外环以外(三林那边的搅拌厂附近)的一个装修队而已,公司只有两块大众化的那种铜牌,其他的破旧不堪。
我们说了下目前的情况,脱排和煤气灶我们肯定不要,那个老板说可以,他其实也不知道,然后我们说那个彩铝的窗子也不好,他说也不知道,他打电话让那个做窗子的人来了,我们说那个材料和我们当初看的肯定不同,然后问他价格,他说3万3一吨(晕,他把进价说了,虽然我们不太好换算为按照市面上的面积计算方法),我们就说按照面积算多少钱,他想了半天,说200一个平方,我们说再去调查。然后就是谈木材的问题,我们说那些板材我们全部不满意,他说已经用了的没有办法,没有用的可以退。就这样大致谈定,我们就出来继续我们的调查。(谈的过程中让他们打电话告诉手下停工)
我们先又去问了下木材,发现那个确实是最差的,而原来的两家正规的装修公司给的材质都是说杉木板,杉木板是实木板,环保方面没有问题,而那个高密板的环保情况不好,因为中国的标准比国家标准差几倍,所以国外用的人多,国内用的人少,那个卖木材的说,这个板子现在只有一些外地人用(不太喜欢他的那个语气)。
然后拿着他们的彩铝的样品去问,一般的给的是160一个平方,后来快回来的时候又试了一家比较大的店,也是160,但是我们快走的时候她问多少平方,说5个平方以上可以便宜10块,我们说10个平方以上,她说那就140、150左右吧。

最后的结果是:和买彩铝的人谈,150给我们,然后找那个老板,那个老板说随便我们怎么做都可以,让我们找工头,工头说没有接到老板的电话,另外明天有事不能谈,我给一个同事打电话,他建议我们逼出那个老板的底线,和老婆商量了下,感觉已经完全失去信任了,再给他做可能问题更多,打算结算以后另外找人做。明天再继续谈。

惨痛的教训是:无论多熟的人一定要签合同,这样说熟人不是熟人的人就更要签,而我们开始太信任他了,我们几乎是没有过问过,只是说要环保一些的,便宜一些的。主要责任还在我们,太大意了,也没有给别人交待清楚。

他们给过我们一个大致的报价,全包,包括实木地板、厨卫、脱排、煤气灶和热水器一共4万3,装修完一次结清,如果我们真的由他们弄,估计他们的采购成本是1万,人工成本是1万,净赚2万3,天啊

真的有人把我们当傻子

前两天已经开始后悔我们的选择,现在更加离谱的事情来了,那个老板给我们买来了脱排和煤气灶,对我老婆说是帅康牌的,我老婆问了下价格,他不愿意说,说不会超过我们的标准,我老婆说1500左右的就可以了,老板说就那个价格,后来老婆去验货,发现脱排的盒子上印的是帅康小旋风,而煤气灶上是帅康飓风,说明书里面则没有牌子,老婆打了煤气灶的说明书上的两个上海的维修电话,一个无法接通,一个不存在,然后跟老板说了,他说现在没有时间,明天再说。
我回来查了一下,恰好有和帅康小旋风相关的新闻,都是伪劣产品新闻,另外那个帅康飓风的煤气灶假得更直接,说明书上没有具体的厂家名称,上网搜索了下,帅康确实有飓风系列产品,但是全部是脱排。
那个老板真的把我们当作什么也不懂的傻子吗?或者是有心试试我们?或者完全是有恃无恐想宰我们一笔?
但愿我们这次遇到的不是黑社会的

软件开发的最大困难其实在于消除重复代码

这个并不是我一时兴起的胡言乱语,而是我的肺腑之言。如果你仔细的审视一下你所在的项目的代码,你可能会发现其中60%以上的代码是何其的类似,充斥其中的都是类似的判断和循环,在项目的框架或者架构稳定下来以后,项目的工作就是每天重复类似的工作,然后就是这些类似的代码的比例越来越大。如果项目的架构或者框架代码不够好,而某一天有一个需求导致这些代码都要进行某种简单或者复杂的更新,那么你的噩梦就来了。
软件开发的最大困难也就随之出现,如果你的框架足够好,共通的需求只会导致一个或者有限的几个地方的修改,如果框架不好,那么你就准备把那个修改重复几十遍或者几百上千遍吧。衡量一个软件的设计是否足够好,我想最重要的标准就是它能多大程度上消除这样的情况。仅仅有了好的架构其实也不够,开发人员可能会复制一段类似的代码,导致超出框架设计的代码重复,这个就是检验项目管理是否足够好了。

设计一个简单易懂、易于扩展、易于维护的框架并不是很难的,结合OO设计的原则和一些设计模式就可以做到,但是问题并没有结束,如何消除业务代码中存在的类似代码结构才是真正的问题所在。
我没有解决方案

当然,软件开发也并不是只有消除重复代码这一个问题,但是我感觉,如果能够较好的消除代码重复,那么软件的开发效率和质量以及可维护性将更好。
PS:我并没有说完全消除重复代码,代码的重复性是不可避免的,典型的例子就是单元测试代码。

如何设计API?

每个人设计API的思路可能都不一样,而我们公司的一些代码的API的设计很有意思,一个例子:
    public AppGroupConfigValueObj get(UserSession _userSession, AppGroupConfigValueObj invo) throws DataException
    {
        long start = System.currentTimeMillis();
        try
        {
            Long id = (Long) invo.getId();
            if (isDebug() )
                SessionLogManager.getInstance().getLogger(this.getClass()).debug("get group" + id);
            AppGroupConfig eb = this.appGroupHome().findByPrimaryKey(id);
            if (isDebug() )
                SessionLogManager.getInstance().getLogger( this.getClass() ).debug("Get( UserSession _userSession, AppGroupConfigValueObj invo) elapsed time = "+ (System.currentTimeMillis()-start));
            return get(eb, invo);
        }
        catch (Exception e)
        {
            throwException(e);
        }
        return null;
    }

    private AppGroupConfigValueObj get(AppGroupConfig eb, AppGroupConfigValueObj invo)
            throws Exception
    {
        AppGroupConfigValueObj vo = (AppGroupConfigValueObj) ServerUtil.getValueObj(eb);

        if (invo.getApps() != null)
        {
            Collection collection = eb.getApplications();
            if (invo.getApps().getCount() == 0)
                vo.setApps(new ValueObjList(collection.size()));
            else
            {
                Iterator it = collection.iterator();
                while (it.hasNext())
                {
                    AppConfig a = (AppConfig) it.next();
                    vo.addApp((AppConfigValueObj) ServerUtil.getValueObj(a));
                }
            }
        }
        return vo;
    }

解释一下,这个API的功能是这样的,主要参数AppGroupConfigValueObj 是一个Map结构的对象,另外包含一些父子关系,如果你需要的是一个轻量级的结果,那么传入的对象只需要设置ID就可以,典型的用法是这样的:
get(cuSession, new AppGroupConfigValueObj(appGroupId))
如果你需要一个重量级的结果,也就是需要它的一些子表的数据,那么就要设置子表的关系,并添加一个空的对象:
                    AppGroupConfigValueObj appVo = new AppGroupConfigValueObj(appGroupId);
                    appVo.addApp(new AppConfigValueObj());
                    get(cuSession,appVo);
还有第三种用法,就是你希望那些子表数据不填充,但是需要知道子表数据有几个,那么你的调用代码就是:
                    AppGroupConfigValueObj appVo = new AppGroupConfigValueObj(appGroupId);
                    appVo.setApps(new ValueObjList());
                    get(cuSession,appVo);

我不知道这种做法源自何处,但是很明显是原来的某位高人,而比我资历更老的一些同事沿用了这个做法并且没有在文档中记录这种方法,当我苦苦寻找一个简单的get(cuSession, appGroupId)方法时没有任何结果,最后看其它部分的代码才知道了这个诀窍。

如何替换\

以前也经常遇到这个问题,但是没有找到解决方案,今天再次遇到这个问题,搜索了下没有什么头绪,很多答案试验了下都是错误的,不得已,自己试吧,最终的结果是:
replaceAll("\\\\", "\\\\\\\\")
就是把字符串中的\替换成两个\,呵呵,变态吧。

没有命名规范的代码是开发人员的地狱

我们已经开始了一个新的阶段,这个阶段的开始并不顺利,因为我遇到了一个原来并不是很常见的问题,我竟然找不到合适的API供我使用,而且是我们系统的基础服务的API,原因不是别的,就是因为命名规范,第一是方法名,原来的很多API的方法名就是开发人员随意取的(我们没有编码规范或者说命名规范),一个公共的Session Bean的Proxy的方法名竟然叫getAll,而它仅仅是返回一个特定的对象的集合,一般这样的方法都应该叫getAllXxxx,第二是有些术语修改了,但是只是把界面上用户可以看到的文字修改了,后台的API的方法名和类名都没有修改,如果你不是相关的开发人员,你怎么可能弄清楚呢?而原来为什么没有修改方法呢?很简单,一些少数的地方使用反射调用,所以用IDE的重构方法可能会漏掉一些地方,所以他们不敢改,举一个真实的例子说明这个命名的修改导致了多么大的问题:
app group-> app
app template -> component
app -> component instance
说实话,在这一点上,我们的产品实在是失败,因为自从我做开发依赖,所去过的公司还没有说哪个公司没有命名规范的。

更新的文章

© 2025 解惑

本主题由Anders Noren提供向上 ↑