分享
 
 
 

翻译TIPatterns--对象数量(Object quantity)

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

对象数量 Object quantity

这里描述的两种模式都可以单独用来控制对象的数量。

单件(Singleton)实际上可以认为是对象池(Object Pool)的一个特例,但是对象池(Object Pool)的应用和单件(Singleton)是如此的不同,将二者区分开来对待是非常必要的。

单件(Singleton)

单件(Singleton)提供一种方法使得某一特定类型存在一个,并且只能是一个对象。它可能是最简单的模式了。单件(Singleton)应用的一个重要方面是提供一个全局的存取点。单件(Singleton)是C里面全局变量的一个替代方法。

除此之外,单件还常常提供注册(registry)和查找(lookup)的功能――你可以从单件那里找到其它对象的引用(find references to other objects)。

单件(Singleton)可以在java库里找到,但是下面提供了一个更直接的例子。

//: singleton:SingletonPattern.java

// The Singleton design pattern: you can

// never instantiate more than one.

package singleton;

import junit.framework.*;

// Since this isn't inherited from a Cloneable

// base class and cloneability isn't added,

// making it final prevents cloneability from

// being added through inheritance:

final class Singleton {

private static Singleton s = new Singleton(47);

private int i;

private Singleton(int x) { i = x; }

public static Singleton getReference() {

return s;

}

public int getValue() { return i; }

public void setValue(int x) { i = x; }

}

public class SingletonPattern extends TestCase {

public void test() {

Singleton s = Singleton.getReference();

String result = "" + s.getValue();

System.out.println(result);

assertEquals(result, "47");

Singleton s2 = Singleton.getReference();

s2.setValue(9);

result = "" + s.getValue();

System.out.println(result);

assertEquals(result, "9");

try {

// Can't do this: compile-time error.

// Singleton s3 = (Singleton)s2.clone();

} catch(Exception e) {

throw new RuntimeException(e);

}

}

public static void main(String[] args) {

junit.textui.TestRunner.run(SingletonPattern.class);

}

} ///:~

单件模式的关键是防止用户以其它任何方式创建对象,而只能用你所提供的方式。所有的构造函数必须被声明为私有的(private),而且必须至少声明一个构造函数,否则编译器就会以package权限帮你创建一个默认的构造函数。

在这一点上(at this point),你自己决定如何创建对象。上面的例子里,对象是静态(statically)创建的,但是你也可以等到客户端提出请求需要创建对象时才创建。不管是哪种情况,(创建的)对象必须以私有方式(privately)存储,而通过公有方法(public methods)来访问。上面的例子里,getReference()返回对单件对象的引用。剩下的接口(getValue()和setValue())是常规的类接口。

另外,Java允许使用克隆(cloning)来创建对象。这个例子里,把这个类声明为final就是为了防止通过克隆方法创建对象。因为Singleton是直接从Object继承下来的,由于clone()是受保护的(protected)方法因而不能用来(复制对象),如果这么做就会导致编译时错误。

但是,如果以public的方式继承了一个重载了clone()方法的类,并且实现了Cloneable接口的话,为了防止对象被克隆,就必须重载clone()方法并抛出一个CloneNotSupportedException异常。这一点在Thinking in Java 第二版的附录A里也讲到了。(你也可以重载clone()方法使它只返回this,但是这样做有一定的欺骗性,客户端程序员会想当然的认为他是在克隆(复制)那个对象,但实际上他处理的还是原来那个对象。)实际上,这么说并不确切,即使是上面所说的情况,你仍然可以使用反射(reflection)来调用clone()方法(真的是这样么?因为Clone()方法是受保护的(protected),所以我也不那么肯定。如果真是这样的话,那就必须得抛出CloneNotSupportedException 异常,这是保证对象不被克隆的唯一方法了。)

练习

1. SingletonPattern.java 总是创建一个对象,即使这个对象从来不会被用到。请用延迟初始化(Lazy Initialization)的方法修改这个程序,使单件对象只在它第一次被用到的时候才创建。

2. Create a registry/lookup service that accepts a Java interface and produces a reference to an object that implements that interface.

对象池(Object pool)

并没有限制说只能创建一个对象。这种技术同样适用于创建固定数量的对象,但是,这种情况下,你就得面对如何共享对象池里的对象这种问题。如果共享对象很成问题得话,你可以考虑以签入(check-in)签出(check-out)共享对象作为一种解决方案。比如,就数据库来说,商业数据库通常会限制某一时刻可以使用的连接的个数。下面这个例子就用对象池(object pool)实现了对这些数据库连接的管理。首先,对象池对象(a pool of objects)的基本管理是作为一个单独的类来实现的。

//: singleton:PoolManager.java

package singleton;

import java.util.*;

public class PoolManager {

private static class PoolItem {

boolean inUse = false;

Object item;

PoolItem(Object item) { this.item = item; }

}

private ArrayList items = new ArrayList();

public void add(Object item) {

items.add(new PoolItem(item));

}

static class EmptyPoolException extends Exception {}

public Object get() throws EmptyPoolException {

for(int i = 0; i < items.size(); i++) {

PoolItem pitem = (PoolItem)items.get(i);

if(pitem.inUse == false) {

pitem.inUse = true;

return pitem.item;

}

}

// Fail early:

throw new EmptyPoolException();

// return null; // Delayed failure

}

public void release(Object item) {

for(int i = 0; i < items.size(); i++) {

PoolItem pitem = (PoolItem)items.get(i);

if(item == pitem.item) {

pitem.inUse = false;

return;

}

}

throw new RuntimeException(item + " not found");

}

} ///:~

//: singleton:ConnectionPoolDemo.java

package singleton;

import junit.framework.*;

interface Connection {

Object get();

void set(Object x);

}

class ConnectionImplementation implements Connection {

public Object get() { return null; }

public void set(Object s) {}

}

class ConnectionPool { // A singleton

private static PoolManager pool = new PoolManager();

public static void addConnections(int number) {

for(int i = 0; i < number; i++)

pool.add(new ConnectionImplementation());

}

public static Connection getConnection()

throws PoolManager.EmptyPoolException {

return (Connection)pool.get();

}

public static void releaseConnection(Connection c) {

pool.release(c);

}

}

public class ConnectionPoolDemo extends TestCase {

static {

ConnectionPool.addConnections(5);

}

public void test() {

Connection c = null;

try {

c = ConnectionPool.getConnection();

} catch (PoolManager.EmptyPoolException e) {

throw new RuntimeException(e);

}

c.set(new Object());

c.get();

ConnectionPool.releaseConnection(c);

}

public void test2() {

Connection c = null;

try {

c = ConnectionPool.getConnection();

} catch (PoolManager.EmptyPoolException e) {

throw new RuntimeException(e);

}

c.set(new Object());

c.get();

ConnectionPool.releaseConnection(c);

}

public static void main(String args[]) {

junit.textui.TestRunner.run(ConnectionPoolDemo.class);

}

} ///:~

Exercises练习先不翻了

1. Add unit tests to ConnectionPoolDemo.java to demonstrate the problem that the client

may release the connection but still continue to use it.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有