Pragmatic Coder

best practices
posts - 8, comments - 0, trackbacks - 0, articles - 0

2006年7月17日

avg_3000 wrote:
> Hi,
>
> Can you suggest a tutorial site for junit and jcoverage that covers
> from the grassroot level since I have no idea on how to use this tools
> in java.

jcoverage is as good as dead. Use Cobertura, which is its replacement.
Cobertura has documentation for running it in Ant; it's even easier in
Maven.
Take a look at <http://cobertura.sourceforge.net/anttaskreference.html>,
since that's what Google would probably have pulled up if you'd searched.

结合使用JUnit和Cobertura可能是不错的选择。

posted @ 2006-09-16 09:59 肖鹏 阅读(242) | 评论 (0)编辑 收藏

〔本站副站发布,主站:designpatterns.cnblogs.com〕

○。背景与背景知识

这是昨天在QQ上举的一个例子。本文并不是从头讲Factory Method模式,仅对其实现细节进行讨论。关于这个模式可以参考wayfarer吕震宇的文章。

一。分析

因为Factory Method(大写的Factory Method表示模式名称)模式的一个目的就是使得创建行为(factory method)(小写的factory method表示创建行为方法)抽象化,由子类实现,从而容易扩展。一个纯的Factory Method模式,其factory method是不能用static来实现的。通常Simple Factory模式才会由static来实现。

但是,一个Factory拥有一个static的创建方法是很诱人的。用户在任何时候只要用类名(Factory的类名)既可以创建出需要的Product。wayfarer 的文章最后给出的DotNet的实现部分就是这样的例子。吕震宇的另一篇文章 (关于Simple Factory模式)的回复中Walkdan给出的解决方案也是这样的。从本质上,这两个例子都不是纯的Factory Method模式或者Simple Factory模式,而是Simple Factory模式和Factory Method模式的组合应用。

引用Walkdan的回复:

Simple Factory最大的好处是把变化集中到了一处。另外,LightSimpleFactory.Create()里面的依赖关系也可以消除,我的做法是:

1. 声明构造子

public interface ILightCreator
{
    Light Create();
}

public class BulbLightCreator: ILightCreator
{
public Light Create()
    {
return new BulbLight();
    }
}
.

2. 注册构造子

creators.Register("Bulb", new BulbLightCreator());
creators.Register("Tube", new TubeLightCreator());
.

3. Simple Factory中创建对象 

public class LightSimpleFactory.Create(string lightType)
{
    ILightCreator creator = creators.Find(lightType);
return creator.Create();
}

构造子其实就是Factory Method。这样, 通过注册构造子,3.中原来的switch()过程被消除,依赖关系随之解除。其中的Register(), Find()容易理解,方法就不写了。

新的类型可通过新注册构造子来实现扩展。当然2中的注册代码仅仅是示例,完全可以放到配置文件中去实现,比如:

<lightCreators>
<add name="Bulb" type="BulbLightCreator,"/>
<add name="Tube" type="TubeLightCreator,"/>
</lightCreators>

其ILightCreator继承体系,是Factory Method模式。LightSimpleFactory和creators的关系Walkdan没有说明,也可实现为Strategy模式。

二。引申问题

  1. 模式中factory method一定要是抽象的吗? NO.你可以定义一个默认的方法,生产某种Product。这样即使Factory没有子类也可以生产这种默认产品。通常这种情况下Factory是一个接口,然后定义一个BasicFactory来生产BasicProduct。其他的Factory由BasicFactory派生。注意,往往Factory和Product是平行的继承结构。
  2. Factory Method解耦了client和concreteProduct,是不是又引入了client和concreteFactory的耦合? 这个问题很好,答案是可能(《head first design patterns》一书中的例子就有这个问题),但是client端不应该依赖concreteFactory。如果依赖concreteFactory,那真是画蛇添足了(见wayfarer的文章)。
  3. Factory Method模式的好处有哪些?
    1. 封装了对象的创建。对象的创建如果使用new来完成,则与实现类(concreteProduct)是紧耦合的。Factory Method的创建行为factory method,返回Product接口,从而解耦了client和concreteProduct。
    2. 易于扩展。相对于Simple Factory模式,Factory Method模式可以通过派生进行扩展。

三。结论

一个纯的Factory Method模式其factory method不可以用static实现,通过与其他模式结合使用可以进行变通。而且通常情况下Factory Method模式都会与其他模式相结合。Abstract Factory模式通常就是用Factory Method模式来实现。

posted @ 2006-09-03 14:21 肖鹏 阅读(416) | 评论 (0)编辑 收藏

欢迎大家加入:
1.读书心得交流,大家可以相约一起读书互相交流
2.技术交流,任何与设计模式相关,包括重构,测试驱动,敏捷开发等,开发中遇到的问题。
要求至少发表过一篇关于设计模式的文章才可以加入。
http://group.qq.com/group_index.shtml?funcid=1&groupid=26227899
友情提示:如果你只打算“听”,不打算“说”或者“问”,对你的帮助会小的多。

posted @ 2006-09-02 22:05 肖鹏 阅读(321) | 评论 (0)编辑 收藏

本书中的大多数原则源于少数几条基本原则。

1.清晰性和简介性是最为重要的:一个模块的用户永远也不应该被模块的行为所迷惑(那样就不清晰了);模块要尽可能的小,但又不能太小〔术语模块(module)在本书中的用法,是指任何可重用的软件组件,从单个方法,到包含多个包的复杂系统都可以是一个模块〕。

2.代码应该被重用,而不是被拷贝。

3.模块之间的相依性应该尽可能降低到最小。

4.错误应该尽早被检测出来,理想情况下是在编译时刻。

posted @ 2006-08-20 14:12 肖鹏 阅读(199) | 评论 (0)编辑 收藏

This is a temporary post that was not deleted. Please delete this manually. (e6a97894-4dd8-4eed-8ba1-b291c8b2bc96)

posted @ 2006-08-20 14:02 肖鹏 阅读(129) | 评论 (0)编辑 收藏

Ant 对文件名是区分大小写的

posted @ 2006-07-27 16:23 肖鹏 阅读(217) | 评论 (0)编辑 收藏

0.引子
通常一个TreeNode (DefaultMutableTreeNode)如果没有子结点,它的节点显示为不可展开的节点,有时候我们希望即使该节点暂时没有装载子结点仍然显示为可展开的节点(如图ParentNode.jpg)。比如,当加载子结点比较耗时或者需要动态刷新,可以延时加载子结点,即在展开节点的时候再去装载子结点。
1.由来及解决方案
该属性取决于,DefaultTreeModel的isLeaf方法
 
    /** 
     * Returns whether the specified node is a leaf node.
     * The way the test is performed depends on the
     * <code>askAllowsChildren</code> setting.
     *
     * @param node the node to check
     * @return true if the node is a leaf node
     *
     * @see #asksAllowsChildren
     * @see TreeModel#isLeaf
     */
publicboolean isLeaf(Object node) {
        if(asksAllowsChildren)
return !((TreeNode)node).getAllowsChildren();
        return ((TreeNode)node).isLeaf();
    }
而asksAllowsChildren由方法setAsksAllowsChildren设定
     /**
      * Sets whether or not to test leafness by asking getAllowsChildren()
      * or isLeaf() to the TreeNodes.  If newvalue is true, getAllowsChildren()
      * is messaged, otherwise isLeaf() is messaged.
      */
publicvoid setAsksAllowsChildren(boolean newValue) {
        asksAllowsChildren = newValue;
    }
注意,在setRoot时可以只设定一次
        model.setRoot(root);

        /*
         * Since nodes are added dynamically in this application, the only true
         * leaf nodes are nodes that don't allow children to be added. (By
         * default, askAllowsChildren is false and all nodes without children
         * are considered to be leaves.)
         *
         * But there's a complication: when the tree structure changes, JTree
         * pre-expands the root node unless it's a leaf. To avoid having the
         * root pre-expanded, we set askAllowsChildren *after* assigning the
         * new root.
         */
        model.setAsksAllowsChildren(true);

而在调用model.nodeStructureChanged(node)前后要分别设置为false和true。这是因为nodeStructureChanged会自动的试图展开节点node,如果isLeaf返回为false。试想,asksAllowsChildren返回true,则一个结点即使没有子结点,只要设置了allowsChildren,对应的treeNodeModel的isLeaf就会返回true。然而当自动展开节点的时候发现并没有子结点,当然就会把图标ParentNode.jpg去掉了。而先把asksAllowsChildren设为false,就不会去试图展开该节点,然后设为true,该节点就会显示为ParentNode.jpg   

    /**
     * Determines whether or not this node is allowed to have children. 
     * If <code>allows</code> is false, all of this node's children are
     * removed.
     * <p>
     * Note: By default, a node allows children.
     *
     * @param	allows	true if this node is allowed to have children
     */
publicvoid setAllowsChildren(boolean allows) {
	if (allows != allowsChildren) {
	    allowsChildren = allows;
	    if (!allowsChildren) {
		removeAllChildren();
	    }
	}
    }
        node.removeAllChildren();
        DefaultTreeModel model = (DefaultTreeModel) cardTreeView.getModel();

        /*
         * To avoid having JTree re-expand the root node, we disable
         * ask-allows-children when we notify JTree about the new node
         * structure.
         */

        model.setAsksAllowsChildren(false);
        model.nodeStructureChanged(node);
        model.setAsksAllowsChildren(true);

posted @ 2006-07-18 09:57 肖鹏 阅读(555) | 评论 (0)编辑 收藏

1.
       vectorObj.trimToSize();   //(optional) insure you won't have empty elements
       ArrayObj[] objs = new ArrayObj[vectorObj.size()];
       vectorObj.toArray(objs);
       return objs.
2.
       Object[] tempObjectArray = vectorObj.toArray();
       ArrayObj[] objs = new ArrayObj[ tempObjectArray.size() ];
       System.arraycopy (tempObjectArray, 0, objs, 0, objs.size() );
       return objs;

posted @ 2006-07-17 17:07 肖鹏 阅读(259) | 评论 (0)编辑 收藏