我想要有两个名为turnOn()和turnOff()的静态函数。
假设objectA调用turnOn(),则objectB调用turnOn()。然后objectA调用turnOff(),它不应该关闭,因为objectB也将它打开。
另外说objectA调用turnOn(),然后objectB调用turnOn()。然后objectB调用turnOff(),它不应该关闭,因为objectA还没有关闭它。
最后,如果objectA和objectB将其打开,它们会在关闭它时关闭。
我正在考虑跟踪调用了多少turnOn和TurnOff,并确保它匹配,但这并不真正准确,因为objectA可以调用turnOff()两次。
那么最好的处理方式是什么?
谢谢!
答案 0 :(得分:1)
这听起来像引用计数
答案 1 :(得分:1)
最简单的方法就像你描述的那样:保持计数。如果您真的担心一个物体在没有打开它时将其关闭,您可以保留已打开它的所有物体的列表,并在它们关闭时从列表中删除它们。如果列表为空,您实际上可以将其关闭。
答案 2 :(得分:0)
编辑:示例代码在c#中 - 我没有意识到这不是一个c#问题。如果你的语言中有哈希表,字典,甚至二维数组(表),那么这个相同的基本模式仍然有效。
听起来你需要一种经过修改的引用计数 - 一个按对象计数的计数。这样的事情怎么样:
public class Switch
{
private bool On;
private Dictionary<object, int> ReferenceCounts = new ...
public void TurnOn(object source)
{
int count = 0;
if(ReferenceCounts.ContainsKey(source))
count = ReferenceCounts[source];
count++;
ReferenceCounts[source] = count;
On = true;
}
public void TurnOff(object source)
{
if(!ReferenceCounts.ContainsKey(source))
return;
int count = ReferenceCounts[source];
count--;
if(count == 0)
ReferenceCounts.Remove(source)
else
ReferenceCounts[source] = count;
if(ReferenceCounts.Count == 0)
this.On = false;
}
}
答案 3 :(得分:0)
我不是100%确定这是你正在寻找的东西,但我想你会想要一个静态数组来确定是什么。另外......公平警告,我没有测试这段代码。这是对我认为您可能要做的事情的粗略估计。
class Switchable {
static var _onObjects:Array=new Array ;
static public function turnOn(obj:Object):Void {
if (_onObjects.indexOf(obj) == -1) {
_onObjects.push(obj);
}
}
static public function turnOff(obj:Object):Void {
var index=_onObjects.indexOf(obj);
if (isOn() && index >= 0) {
_onObjects=_onObjects.splice(index,1);
}
}
static public function isOn():Boolean {
return _onObjects.length > 0;
}
}
class ObjectA {
public function Foo():Void {
Switchable.turnOn(this);
}
public function Bar():Void {
Switchable.turnOff(this);
}
}
class ObjectB {
public function Foo():Void {
Switchable.turnOn(this);
}
public function Bar():Void {
Switchable.turnOff(this);
}
}
class Test {
static public function Main():Void {
trace(Switchable.isOn());
var a:ObjectA=new ObjectA ;
var b:ObjectB=new ObjectB ;
a.Foo();
trace(Switchable.isOn());
b.Foo();
trace(Switchable.isOn());
a.Bar();
trace(Switchable.isOn());
b.Bar();
trace(Switchable.isOn());
}
}
答案 4 :(得分:0)
解决方案分为两部分: - 如其他地方所建议的静态对象计数器 - 以及一个per-object isTurnedOn标志,可防止对象打开或关闭两次,这与伪代码的行相似:
...
private static in count = 0;
private boolean isTurnedOn = false;
...
public void TurnON() {
if (!isTurnedOn) {
isTurnedOn = true;
++count;
}
}
public void TurnOff() {
if (isTurnedOn) {
isTunedOn = false;
--count;
if (count == 0) {
// the conter reached 0, do soemthing
// but do not forget to protect against concurretn access
}
}
请注意,此构造允许重复打开和关闭对象。如果你想阻止这种情况,你可能应该为isTurnedOn和isTurnedOff使用两个单独的布尔值。