ivaneeo's blog

自由的力量,自由的生活。

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

#

你有一个reference object(引用对象),很小且不可变(immutable),而且不易管理。

将它变成一个value object(实值对象)。

Change Reference to Value.png
posted @ 2005-09-05 09:47 ivaneeo 阅读(256) | 评论 (0)编辑 收藏

在debian中使用sudo必须先添加用户到sudo中,才可以以root身份执行.
修改sudo列表使用visudo命令.

添加内容

任何程序不要用sudo执行不要密码
你的用户名 ALL=NOPASSWD:ALL

要密码的
你的用户名 ALL=PASSWD:ALL 密码为你的用户名密码非root的

如果限制程序用sudo把all换成相应的程序
只有在普通用户下用gksu 运行程序时才用root密码
因为gksu 默任时root用户

posted @ 2005-09-02 14:07 ivaneeo 阅读(434) | 评论 (0)编辑 收藏

范例(Examples)
在Replace Data Value with Object(175)一节中,我留下了一个重构后的程序,本节范例就从它开始。我们有下列的Customer class:
class Customer {
    public Customer(String name) {
       _name = name;
    }

    public String getName() {
       return _name;
    }
    private final String _name;
}
它被以下的order class使用:
class Order...
    public Order(String customer) {
       _customer = new Customer(customer);
    }

    public String getCustomer() {
       return _customer.getName();
    }
   
    public void setCustomer(String arg) {
       _customer = new Customer(arg);
    }
    private Customer _customer;


此外,还有一些代码也会使用Customer对象:
private static int numberOfOrdersFor(Collection orders, String customer) {
    int result = 0;
    Iterator iter = orders.iterator();
    while(iter.hasNext()) {
       Order each = (Order)iter.next();
       if(each.getCustomer().equals(customer)) result ++;
    }
    return result;
}
到目前为止,Customer对象还是value object。就算多份定单属于同一客户,但每个order对象还是拥有各自的Customer对象。我希望改变这一现状,使得一旦同一客户拥有多份不同定单,代表这些定单的所有Order对象就可以共享同一个Customer对象。

首先我使用Replace Constructor with Factory Method(304)。这样,我就可以控制Customer对象的创建过程,这在以后会是非常重要的。我在Customer class中定义这个factory method
class Customer {
    public static Customer create(String name) {
       return new Customer(name);
    }
}
然后我把[对构造函数的调用]替换成[对factory method的调用]:
class Order {
    public Order(String customer) {
       _customer = Customer.create(customer);
    }
}
然后我再把构造函数声明为private:
class Customer {
    private Customer(String name) {
       _name = name;
    }
}
现在,我必须决定如何访问Customer对象。我比较喜欢通过另一个对象(例如Order class中的一个值域)来访问它。但是本例并没有这样一个明显的值域可用于访问Customer对象。在这种情况下,我通常会创建一个注册(登录)对象,作为访问点。为了简化我们的例子,我把Customer对象保存在Customer class的一个static值域中,让Customer class作为访问点:
private static Dictionary _instance = new Hashtable();

然后我得决定:应该在接到请求时创建新的Customer对象,还是应该预先将它们创建好。这里我选择后者。在应用程序的启动代码(start-up code)中,我先把需要使用的Customer对象加载妥当。这些对象可能来自数据库,也可能来自文件。为求简单起见,我在代码中明确生成这些对象。反正以后我总是可以使用Substitute Algorithm(139)来改变它们的创建方式。
class Customer...
    static void loadCustomers() {
       new Customer("Lemon Car Hire").store();
        new Customer("Associated Coffee Machines").store();

        new Customer("Bilston Gasworks").store();
    }
    private void store() {
       _instance.put(this.getName(), this);
    }
现在,我要修改factory method,让它返回预先创建好的Customer对象:
public static Customer create(String name) {
    return (Customer)_instance.get(name);
}
由于create()总是返回既有的Customer对象,所以我应该使用Rename Method(273)修改这个factory method的名称,以便强调(说明)这一点。
class Customer...
public static Customer getNamed(String name) {
    return (Customer)_instances.get(name);
}
posted @ 2005-09-01 14:16 ivaneeo 阅读(180) | 评论 (0)编辑 收藏

作法(Mechanics)
    • 使用Replace Constructor with Factor Method(304)。
    • 编译,测试。
    • 决定由什么对象负责提供访问新对象的途径。
        • ==》可能是个静态字典(static dictionary)或一个注册对象(registry object)
        • ==》你也可以使用多个对象作为新对象的访问点(access point)。
    • 决定这些reference object应该预先创建好,或是应该动态创建。
        • ==》如果这些reference object是预先创建好的,而你必须从内存中被它们读取出来,那么就得确保它们在被需要的时候能够被及时加载。
    • 修改factory method,令它返回reference object。
        • ==》如果对象是预先创建好的,你就需要考虑:万一有人索求一个其实并不存在的对象,要如何处理错误?
        • ==》你可能希望对factory method使用Rename Method(273),使其传达这样的信息;它返回的是一个既存对象。
    • 编译,测试。
posted @ 2005-09-01 11:13 ivaneeo 阅读(157) | 评论 (0)编辑 收藏

动机(Motivation)
在许多系统中,你都可以对对象做一个有用的分类:reference object和value objects。前者就像[客户]、[帐户]这样的东西,每个对象都代表真实世界中的一个实物,你可以直接以相等操作符(==,用来检验同一性, identity)检查两个对象是否相等。后者则是像[日期]、[钱]这样的东西,它们完全由其所含的数据值来定义,你并不在意副本的存在;系统中或许存 在成百上千个内容为“1/1/2000”的[日期]对象。当然,你也需要知道两个value objects是否相等,所以你需要覆写equals()(以及hashCode())。


要在reference object和value object之间做选择有时并不容易。有时侯,你会从一个简单的value object开始,在其中保存少量不可修改的数据。而后,你可能会希望给这个对象加入一些可修改数据,并确保对任何一个对象的修改都能影响到所有引用此一对象的地方。这时候你就需要将这个对象变成一个reference object。
posted @ 2005-09-01 10:37 ivaneeo 阅读(171) | 评论 (0)编辑 收藏

你有一个class,衍生出许多相等实体(equal instances),你希望将它们替换为单一对象。

将这个value object(实值对象)变成一个reference object(引用对象)。

Change_Value_to_Reference.png
posted @ 2005-09-01 10:22 ivaneeo 阅读(171) | 评论 (0)编辑 收藏

范例(Examples)
下面有一个代表[定单]的Order class,其中以一个字符串记录定单客户。现在,我希望改为以一个对象来表示客户信息,这样我就有充裕的弹性保存客户地址、信用等级等等信息,也得以安置这些信息的操作行为。Order class最初如下:
class Order...
    public Order(String customer) {
       _customer = cusomer;
    }

    public String getCustomer() {
       return _customer;
    }
   
    public void setCustomer(String arg) {
       _customer = arg;
    }
    private String _customer;

Order class的客户代码可能像下面这样:
private static int numberOfOrdersFor(Collection orders, String customer) {
    int result = 0;
    Iterator iter = orders.iterator();
    while(iter.hasNext()) {
       Order each = (Order)iter.next();
       if(each.getCustomer().equals(customer)) result ++;
    }
    return result;
}

首先,我要新建一个Customer class来表示[客户]概念。然后在这个class中建立一个final值域,用以保存一个字符串,这是Order class目前所使用的。我将这个新值域命名为_name,因为这个字符串的用途就是记录客户名称。此外我还要为这个字符串加上取值函数(getter) 和构造函数(constructor)。
class Customer {
    public Customer(String name) {
       _name = name;
    }

    public String getName() {
       return _name;
    }
    private final String _name;
}

现在,我要将Order中的_customer值域的型别修改为Customer;并修改所有引用此一值域的函数,让它们恰当地改而引用Customer实体。其中取值函数和构造函数的修改都很简单;至于设值函数(setter),我让它创建一份Customer实体。
class Order...
    public Order(String customer) {
       _customer = new Customer(customer);
    }

    public String getCustomer() {
       return _customer.getName();
    }
   
    public void setCustomer(String arg) {
       _customer = new Customer(arg);
    }
    private Customer _customer;

设值函数需要创建一份Customer实体,这是因为以前的字符串是个实值对象(value object),所以现在的Customer对象也应该是个实值对象。这也就意味每个Order对象都包含自己的一个Customer对象。注意这样一条 规则:实值对象应该是不可修改内容的--这便可以避免一些讨厌的[别名](aliasing)错误。日后或许我会想让Customer对象成为引用对象(reference object),但那是另一项重构手法的责任。现在我可以编译并测试了。

我需要观察Order class中的_customer值域的操作函数,并作出一些修改,使它更好地反映出修改后的新形势。对于取值函数,我会用Rename Method(273)改变其名称,让它更清晰地表示,它所返回的是消费者名称,而不是个Customer对象。
public String getCustomerName() {
    return _customer.getName();
}

至于构造函数和设值函数,我就不必修改其签名(signature)了,但参数名称得改:
public Order(String customerName) {
    _customer = new Customer(customerName);
}
public void setCustomer(String customerName) {
    _customer = new Customer(customerName);
}

本次 重构到此为止。但是,这个案例和其他很多案例一样,还需要一个后续步骤。如果想在Customer中加入信用等级、地址之类的其他信息,现在还做不到,因为目前的Customer还是被作为实值对象(value object)来对待,每个Order对象都拥有自己的Customer对象。为了给Customer class加上信用等级、地址之类的属性,我必须运用Change Value to Reference(179),这么一来属于同一客户的所有Order对象就可以共享同一个Customer对象。马上你就可以看到这个例子。
posted @ 2005-09-01 09:59 ivaneeo 阅读(190) | 评论 (0)编辑 收藏

作法(Mechanics)
    • 为[待替换数值]新建一个class,在其中声明一个final值域,其型别和source class中的[待替换数值]型别一样。然后在新class中加入这个值域的取值函数(getter),再加上一个[接受此值域为参数]的构造函数。
    • 编译。
    • 将source class中的[待替换数值值域]的型别改为上述的新建class。
    • 修改source class中此一值域的取值函数(getter),令它调用新建class的取值函数。
    • 如果source class构造函数中提及这个[待替换值域](多半是赋值动作),我们就修改构造函数,令它改用新class的构造函数来对值域进行赋值动作。
    • 修改source class中[待替换值域]的设值函数(setter),令它为新class创建一个实体。
    • 编译,测试。
    • 现在,你有可能需要对新class使用Change Value to Reference(179)。
posted @ 2005-09-01 09:28 ivaneeo 阅读(146) | 评论 (0)编辑 收藏

动机(Motivation)
一开始你可能会用一个字符串来表示[电话号码]概念,但是随后你就会发现,电话号码需要[格式化]、[抽取区号]之类的特殊行为。当这些臭味开始出现,你就应该将数据值(data value)变成对象(object)。
posted @ 2005-09-01 09:17 ivaneeo 阅读(182) | 评论 (0)编辑 收藏

你有一笔数据项(data item),需要额外的数据和行为。

将这笔数据项变成一个对象。

Replace_Data_Value_with_Object.png


posted @ 2005-08-31 16:32 ivaneeo 阅读(163) | 评论 (0)编辑 收藏

仅列出标题
共67页: First 上一页 41 42 43 44 45 46 47 48 49 下一页 Last