ライフサイクルを持つクラスがあります。つまり、時間が経過すると、そのプロパティの一部が変化します (つまり、しばらく水を飲まないと喉が渇きます)。今私がやっていることは、最初のメソッドでいくつかのメソッドを常に呼び出している別のクラスを持っていることです (while ループは 1 分あたり x の時間を呼び出しました)。行動。ただし、よりクリーンなものが必要です。おそらく、オブジェクトを「監視」する責任をよりエレガントな方法で分離するために、いくつかのパターンを使用できます。それが明確であることを願っています。それ以外の場合は、いくつかのコードを提供できます
5 に答える
「ティック」を使用できます。ティック変数 (整数) を使用します。メソッドを呼び出すたびに tick 変数を 1 増やします。
たとえば、250 ティック後にキャラクター (またはその他) に喉が渇いたと感じさせたい場合は、単純にティックを 250 で剰余除算し、結果が 0 かどうかを確認します。
状態を自動的に変更するオブジェクトを持つ私見は良いことではないので、このための設計パターンは存在しないと思います。
creationDate
誰かがあなたに提案したように、オブジェクトに変数(または同様のもの)とオブジェクトの「ニーズ」をチェックするいくつかのメソッドを含めることは良い考えだと思います。例えば:
boolean isThirsty(){
return (now - lastDrinkDate > MAX_INTERVAL);
}
私がすることは、オブジェクトのプロパティとしてオブジェクトの初期化時にシステムの日付を記録することです。次に、オブジェクトを「監視」する代わりに、初期化時刻と現在の時刻を比較して状態を返すメソッドをオブジェクト内に配置します。
while ループで問題が解決するとは限りませんが、実装によっては、while ループが必要ない場合があります (必要に応じて、このオブジェクト メソッドを呼び出すことができます)。
編集:
例(抽象化されています。これは言語ではありません。プラットフォームのメソッドを置き換えてください)
//MyObject.h
enum {
NormalObjectState = 0,
ThirstyObjectState = 1
} ObjectState;
SystemDate _initSystemDate;
-(ObjectState) returnObjectState;
//MyObject.m
- (MyObject) init {
SystemDate currentTime = GetSystemTime();
_initSystemTime = currentTime;
return self;
}
-(ObjectState) returnObjectState {
SystemDate currentTime = GetSystemTime();
SystemDateInterval timeInterval = GetTimePassed(_initSystemTime, CurrentTime);
ObjectState currentState = NormalObjectState;
if (timeInterval > 60) { //minute passed
currentState = ThirstyObjectState;
}
return currentState;
}
//in your program code
#import MyObject.h
//...
while (x) {
ObjectState currentObjectState = [object returnObjectState];
if (currentObjectState == NormalObjectState) {
print ("I'm normal");
} else {
print ("I'm thirsty");
[thisClass drinkWater];
}
}
- (void) drinkWater {
SystemDate currentTime = GetSystemTime();
_initSystemTime = currentTime;
}
まず、変更は間違いなくクラス内で処理する必要があります。それはちょうど適切な OOP です。他の場所で述べたように、これを行う最善の方法は、要求された時点で各値を計算することです。
それができない場合は、タイマーを実行します。理想的には、ある種のキュー (Java EventQueue など) で物事を実行するものを取得できます。これにより、すべてが 1 つのスレッドに保持されます。それ以外の場合は、マルチスレッドで実行されているため、多少興味深いことがあります。
ほとんどの場合、他のクラスからコードを取得して、このクラスに配置できます。とにかく、そのコードはすでにこれらの問題を解決しなければなりませんでした。
タイマーを開始する場所はトリックになる可能性があります。なんらかのアクティブ化メソッドが既にある場合は、準備完了です。それ以外の場合は、マルチスレッドでない場合は、コンストラクターで開始するだけで、クラスが最初からすぐに実行できるようになります。(セッションで数回開始および停止したい場合を除きます。)これはマルチスレッドで実行することもできますが、あなた (または他の誰か) が不注意または忘れると、クラスが完全に初期化される前に他のコードがクラスにアクセスする可能性があります。 . もちろん、タイマーが実行されていないと、新しく構築されたインスタンスはまだ完全に初期化されていないため、アクティブ化メソッドを使用しても同じ問題が発生します。(私は 2 つの間でぐらつきがちで、それぞれのケースで最も悪い解決策を選びます。マルチスレッドでないことを願っています。)
また、セッション全体でクラス インスタンスが必要ない場合は、"dispose" メソッドと、それを呼び出す場所が必要になります。(「アクティブ化」メソッドがある場合は、代わりに「非アクティブ化」メソッドにします。セッションでオブジェクトを数回アクティブ化および非アクティブ化することは理にかなっています。)