मैं कुछ कोड को रीक्रिएट करने पर काम कर रहा हूं, और मुझे लगता है कि मैंने खरगोश के छेद के नीचे पहला कदम उठाया हो सकता है। मैं जावा में उदाहरण लिख रहा हूं, लेकिन मुझे लगता है कि यह अज्ञेयवादी हो सकता है।
मेरे पास एक इंटरफ़ेस के Foo
रूप में परिभाषित है
public interface Foo {
int getX();
int getY();
int getZ();
}
और एक कार्यान्वयन के रूप में
public final class DefaultFoo implements Foo {
public DefaultFoo(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
private final int x;
private final int y;
private final int z;
}
मेरे पास एक इंटरफ़ेस भी है जो MutableFoo
मिलान म्यूटेटर प्रदान करता है
/**
* This class extends Foo, because a 'write-only' instance should not
* be possible and a bit counter-intuitive.
*/
public interface MutableFoo extends Foo {
void setX(int newX);
void setY(int newY);
void setZ(int newZ);
}
वहाँ कार्यान्वयन के कुछ जोड़े MutableFoo
मौजूद हो सकते हैं (मैंने उन्हें अभी तक लागू नहीं किया है)। उनमें से एक है
public final class DefaultMutableFoo implements MutableFoo {
/**
* A DefaultMutableFoo is not conceptually constructed
* without all values being set.
*/
public DefaultMutableFoo(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getX() {
return x;
}
public void setX(int newX) {
this.x = newX;
}
public int getY() {
return y;
}
public void setY(int newY) {
this.y = newY;
}
public int getZ() {
return z;
}
public void setZ(int newZ) {
this.z = newZ;
}
private int x;
private int y;
private int z;
}
मेरे द्वारा विभाजित किए जाने का कारण यह है क्योंकि यह प्रत्येक के लिए समान रूप से उपयोग किए जाने की संभावना है। मतलब, यह समान रूप से संभावना है कि इन वर्गों का उपयोग करने वाला कोई व्यक्ति एक अपरिवर्तनीय उदाहरण चाहता है, क्योंकि यह वह है जो एक परिवर्तनशील चाहते हैं।
प्राथमिक उपयोग-मामला जो मेरे पास है वह एक इंटरफ़ेस है जिसे StatSet
गेम (हिट पॉइंट, अटैक, डिफेंस) के लिए कुछ निश्चित विवरणों का प्रतिनिधित्व करता है। हालांकि, "प्रभावी" आँकड़े, या वास्तविक आँकड़े, आधार आँकड़ों के परिणामस्वरूप होते हैं, जिन्हें कभी नहीं बदला जा सकता है, और प्रशिक्षित आँकड़े, जिन्हें बढ़ाया जा सकता है। इन दोनों से संबंधित हैं
/**
* The EffectiveStats can never be modified independently of either the baseStats
* or trained stats. As such, this StatSet must never provide mutators.
*/
public StatSet calculateEffectiveStats() {
int effectiveHitpoints =
baseStats.getHitpoints() + (trainedStats.getHitpoints() / 4);
int effectiveAttack =
baseStats.getAttack() + (trainedStats.getAttack() / 4);
int effectiveDefense =
baseStats.getDefense() + (trainedStats.getDefense() / 4);
return StatSetFactory.createImmutableStatSet(effectiveHitpoints, effectiveAttack, effectiveDefense);
}
प्रशिक्षित स्टैट्स को हर लड़ाई की तरह बढ़ाया जाता है
public void grantExperience() {
int hitpointsReward = 0;
int attackReward = 0;
int defenseReward = 0;
final StatSet enemyStats = enemy.getEffectiveStats();
final StatSet currentStats = player.getEffectiveStats();
if (enemyStats.getHitpoints() >= currentStats.getHitpoints()) {
hitpointsReward++;
}
if (enemyStats.getAttack() >= currentStats.getAttack()) {
attackReward++;
}
if (enemyStats.getDefense() >= currentStats.getDefense()) {
defenseReward++;
}
final MutableStatSet trainedStats = player.getTrainedStats();
trainedStats.increaseHitpoints(hitpointsReward);
trainedStats.increaseAttack(attackReward);
trainedStats.increaseDefense(defenseReward);
}
लेकिन वे सिर्फ लड़ाई के बाद नहीं बढ़े हैं। कुछ वस्तुओं का उपयोग करना, कुछ युक्तियों को नियोजित करना, युद्धक्षेत्र का चतुर उपयोग सभी अलग अनुभव प्रदान कर सकते हैं।
अब मेरे सवालों के लिए:
- क्या एक्सेसर्स और म्यूटेटर्स द्वारा अलग-अलग इंटरफेस में विभाजन के लिए एक नाम है?
- क्या इस तरह से उन्हें विभाजित करना 'सही' दृष्टिकोण है यदि वे समान रूप से उपयोग किए जाने की संभावना रखते हैं, या क्या एक अलग, अधिक स्वीकृत पैटर्न है जिसे मुझे इसके बजाय उपयोग करना चाहिए (उदाहरण के लिए
Foo foo = FooFactory.createImmutableFoo();
जो रिटर्न दे सकता हैDefaultFoo
याDefaultMutableFoo
छिपा हुआ है क्योंकिcreateImmutableFoo
रिटर्नFoo
)? - क्या इस पैटर्न का उपयोग करने के लिए कोई तुरंत पूर्वाभास हो सकता है, इंटरफ़ेस पदानुक्रम को जटिल करने के लिए बचा सकता है?
इसका कारण मैंने इसे इस तरह से डिजाइन करना शुरू कर दिया है क्योंकि मैं इस मानसिकता का हूं कि एक इंटरफ़ेस के सभी कार्यान्वयनकर्ताओं को सरलतम इंटरफ़ेस का पालन करना चाहिए, और कुछ भी नहीं प्रदान करना चाहिए। इंटरफ़ेस में बसने वालों को जोड़कर, अब प्रभावी आँकड़ों को इसके भागों से स्वतंत्र रूप से संशोधित किया जा सकता है।
EffectiveStatSet
हम किसी भी तरह से कार्यक्षमता का विस्तार नहीं कर रहे हैं, क्योंकि इसके लिए एक नया वर्ग बनाना बहुत मायने नहीं रखता है। हम कार्यान्वयन को बदल सकते हैं, और EffectiveStatSet
दो अलग-अलग का एक संयोजन बना सकते हैं StatSets
, लेकिन मुझे लगता है कि यह सही समाधान नहीं है;
public class EffectiveStatSet implements StatSet {
public EffectiveStatSet(StatSet baseStats, StatSet trainedStats) {
// ...
}
public int getHitpoints() {
return baseStats.getHitpoints() + (trainedStats.getHitpoints() / 4);
}
}