2010-10-15 45 views
0

这更像是一个设计问题,我在此发布的主要目的是获得关于问题解决方案的各种输入。连续计数器设计问题

我想创建的是一个计数器。计数器可能是单值(单个字符/数字)或多值。所以我设计了这样一个层次(READ键=计数器):

       Key 
           | 
     ----------------------------------------------- 
     |     |    |    | 
SingleValueKey MultiValueKey NumericKey AlphaNumericKey 
    (there could be further mix and match between these types) 

现在在设计MultiValueKey,我以为我可以简单地使用正SingleValueKey的集合来创建一个正字符计数器。对于例如一个2位(多值)计数器将使用一个大小为2的SingleValue数值计数器的数组。我最终计划的是一个可变长度的字母数字键集,基数为64,适用于短网址。数字上下文只是一个简单的例子。

我现在被卡住的是低阶计数器的“滚动”或“包裹”到递增更高阶的计数器中。敌人,例如对于一个2位数的计数器,一旦单位位置达到9,下一个数字将在单位位置绕回到0并且十位增加1.

我有几个方面需要您对如何反馈应该这样做:

  1. 单值计数器应该在它达到其最大值时抛出异常?还是应该自动换行?还是应该允许用户指定应采取哪些方法?
  2. 如果单个计数器应该抛出一个异常(我认为),应该有一个“重置”方法将计数器重置为开始 - 调用者应该处理异常并调用重置(在它开始之前/之后)以增加更高阶的计数器)。这会是一个很好的设计吗?
  3. 当计数器刚刚初始化时 - 新的SingleValueNumericKey() - 计数器的值应该是多少?它是否应该准备好使用,没有价值,或者它应该是它的价值集中的第一个价值?
  4. 类似于prev问题,当调用“reset”方法时,计数器的值应该是多少?

请帮助我在这里输入您的宝贵意见。如果您对设计本身有任何建议,欢迎!如果我拿走从这个线程的东西,我要提到它在我提交 - 这样你才会有信用的建议:)

谢谢
Madhur Tanwani

编辑:添加我的最后用例来澄清杰森的所有问题。

回答

0

帮你一个忙,创建一些用例,所以你很清楚你需要什么。如果你只是在谈论N位数字计数器,你看起来像是过度杀伤。但也许不是。

+0

我最终计划的是一个字母数字键集,基数为64,适用于短网址。数字上下文只是一个简单的例子。 – madhurtanwani 2010-10-15 11:39:44

1

设计每个柜台以了解更高阶的柜台,所以你只需要在柜台上与某个地方互动。您可以使用具有指定位数的构造函数来创建较少的数字的更高位计数器。当您增加计数器时,您可以将其与正在使用的基数(每位数值的数量)进行比较并将其重置为零并递增较高的计数器。获取值也可以递归地完成。

很好地做这个设计没有例外。在出现例外情况时应使用例外情况,超出通常预期的情况。例如,当文件读取失败,或者网络套接字不能连接时。您不应该将异常用于计数器滚动等正常事件。

重置方法应该将所有计数器都设置为零,这是它们在初始化时应该具有的默认值。实际上,重置方法可以使用相同的链接,因此当您在计数器上调用reset时,它将将其值重置为零,并在其较高计数器上调用reset(如果已设置)。

你可以建立在这个相同的设计上,以抽象出像用于表示每个值的特定字符这样的概念。你也可以使用函数来获取整个计数器集作为字符串,递归地使用每个值的字符的抽象函数,以便可以像设计一样对其进行子类化。

 
public class Key { 
    private Key higherKey; 
    private int base; 
    private int value; 

    public Key(int base, int numberOfDigits) { 
    this.base = base; 
    if (numberOFDigits > 1) 
     this.higherKey = new Key(base, numberOfDigits - 1); 
    this.value = 0; 
    } 

    public int getNumericValue() { 
    int value = this.value; 
    if (this.higherKey != null) 
     value += (this.higherKey.getValue() * this.base); 
    return value; 
    } 

    public void increment() { 
    this.value++; 
    if (this.value >= this.base) { 
     this.value++; 
     if (this.higherKey != null) 
     this.higherKey.increment(); 
    } 
    } 
} 
+0

感谢您对异常和重置的意见。 我认为应该抛出一个异常的原因是,一个数字/字符计数器在达到其最大限制时应该不知道应该完成什么(除非明确指定 - 哪一个将是其他设计)。 但我同意 - 你对异常使用的建议确实有道理。谢谢! – madhurtanwani 2010-10-15 11:51:57

+1

在这种情况下,您可以使用观察者模式来通知溢出事件的高阶计数器。 – 2010-10-15 11:56:26

+0

但是,我不确定“连接”模式是否合适。单个数字计数器知道的应该比它应该运作的更多。 一位同事的建议是使用Mediator模式 - 在n-SingleValueKey对象的顶部有一个人。每当单一价值的柜台滚动时,它应该与调解员(导演和GoF一样)亲密。调解员应该决定下一步做什么 - 你认为怎么样? – madhurtanwani 2010-10-15 11:56:42