mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 20:58:35 +00:00
c983af6003
* Added Hindi Translation for adapter, aggregator, ambassador, api-gateway and arrange-act-assert pattern * Added hndi translation for async-method-invocation, balking, bridge, builder and buisness-delegate pattern * Added hindi translation for bytecode, caching, chain-of-responsibility, citcuit-breaker pattern * Added hindi translation for client-session, collecting-parameter, collection-pipeline, combinator, command pattern
242 lines
12 KiB
Markdown
242 lines
12 KiB
Markdown
---
|
|
title: Bytecode
|
|
category: Behavioral
|
|
language: hi
|
|
tag:
|
|
- Game programming
|
|
---
|
|
|
|
## हेतु
|
|
|
|
वर्चुअल मशीन के लिए निर्देशों के रूप में एन्कोडिंग व्यवहार की अनुमति देता है।
|
|
|
|
## व्याख्या
|
|
|
|
वास्तविक दुनिया का उदाहरण
|
|
|
|
> एक टीम एक नए गेम पर काम कर रही है जहां जादूगर एक-दूसरे के खिलाफ लड़ते हैं। जादूगर का व्यवहार
|
|
> प्लेटेस्टिंग के माध्यम से सैकड़ों बार सावधानीपूर्वक समायोजित और पुनरावृत्त करने की आवश्यकता है। यह
|
|
> हर बार जब गेम डिजाइनर बदलाव करना चाहता है तो प्रोग्रामर से बदलाव करने के लिए कहना सबसे अच्छा है
|
|
> व्यवहार, इसलिए विज़ार्ड व्यवहार को डेटा-संचालित वर्चुअल मशीन के रूप में कार्यान्वित किया जाता है।
|
|
|
|
साफ़ शब्दों में
|
|
|
|
> बाइटकोड पैटर्न कोड के बजाय डेटा द्वारा संचालित व्यवहार को सक्षम बनाता है।
|
|
|
|
[Gameprogrammingpatterns.com](https://gameprogrammingpatterns.com/bytecode.html) प्रलेखन
|
|
बताता है:
|
|
|
|
> एक निर्देश सेट निम्न-स्तरीय संचालन को परिभाषित करता है जिन्हें निष्पादित किया जा सकता है। की एक श्रृंखला
|
|
> निर्देश बाइट्स के अनुक्रम के रूप में एन्कोड किया गया है। एक वर्चुअल मशीन इन निर्देशों को एक-एक करके क्रियान्वित करती है
|
|
> एक समय में, मध्यवर्ती मानों के लिए स्टैक का उपयोग करना। अनुदेशों के संयोजन से, जटिल उच्च-स्तरीय
|
|
> व्यवहार को परिभाषित किया जा सकता है।
|
|
|
|
**प्रोग्रामेटिक उदाहरण**
|
|
|
|
सबसे महत्वपूर्ण गेम ऑब्जेक्ट में से एक `Wizard` वर्ग है।
|
|
|
|
```java
|
|
@AllArgsConstructor
|
|
@Setter
|
|
@Getter
|
|
@Slf4j
|
|
public class Wizard {
|
|
|
|
private int health;
|
|
private int agility;
|
|
private int wisdom;
|
|
private int numberOfPlayedSounds;
|
|
private int numberOfSpawnedParticles;
|
|
|
|
public void playSound() {
|
|
LOGGER.info("Playing sound");
|
|
numberOfPlayedSounds++;
|
|
}
|
|
|
|
public void spawnParticles() {
|
|
LOGGER.info("Spawning particles");
|
|
numberOfSpawnedParticles++;
|
|
}
|
|
}
|
|
```
|
|
|
|
इसके बाद, हम अपनी वर्चुअल मशीन के लिए उपलब्ध निर्देश दिखाते हैं। प्रत्येक निर्देश का अपना है
|
|
यह स्टैक डेटा के साथ कैसे संचालित होता है, इसका अपना शब्दार्थ। उदाहरण के लिए, ADD निर्देश शीर्ष पर है
|
|
स्टैक से दो आइटम, उन्हें एक साथ जोड़ता है और परिणाम को स्टैक पर भेजता है।
|
|
|
|
```java
|
|
@AllArgsConstructor
|
|
@Getter
|
|
public enum Instruction {
|
|
|
|
LITERAL(1), // e.g. "LITERAL 0", push 0 to stack
|
|
SET_HEALTH(2), // e.g. "SET_HEALTH", pop health and wizard number, call set health
|
|
SET_WISDOM(3), // e.g. "SET_WISDOM", pop wisdom and wizard number, call set wisdom
|
|
SET_AGILITY(4), // e.g. "SET_AGILITY", pop agility and wizard number, call set agility
|
|
PLAY_SOUND(5), // e.g. "PLAY_SOUND", pop value as wizard number, call play sound
|
|
SPAWN_PARTICLES(6), // e.g. "SPAWN_PARTICLES", pop value as wizard number, call spawn particles
|
|
GET_HEALTH(7), // e.g. "GET_HEALTH", pop value as wizard number, push wizard's health
|
|
GET_AGILITY(8), // e.g. "GET_AGILITY", pop value as wizard number, push wizard's agility
|
|
GET_WISDOM(9), // e.g. "GET_WISDOM", pop value as wizard number, push wizard's wisdom
|
|
ADD(10), // e.g. "ADD", pop 2 values, push their sum
|
|
DIVIDE(11); // e.g. "DIVIDE", pop 2 values, push their division
|
|
// ...
|
|
}
|
|
```
|
|
|
|
हमारे उदाहरण के केंद्र में `VirtualMachine` वर्ग है। यह निर्देशों को इनपुट के रूप में लेता है और
|
|
गेम ऑब्जेक्ट व्यवहार प्रदान करने के लिए उन्हें निष्पादित करता है।
|
|
|
|
```java
|
|
@Getter
|
|
@Slf4j
|
|
public class VirtualMachine {
|
|
|
|
private final Stack<Integer> stack = new Stack<>();
|
|
|
|
private final Wizard[] wizards = new Wizard[2];
|
|
|
|
public VirtualMachine() {
|
|
wizards[0] = new Wizard(randomInt(3, 32), randomInt(3, 32), randomInt(3, 32),
|
|
0, 0);
|
|
wizards[1] = new Wizard(randomInt(3, 32), randomInt(3, 32), randomInt(3, 32),
|
|
0, 0);
|
|
}
|
|
|
|
public VirtualMachine(Wizard wizard1, Wizard wizard2) {
|
|
wizards[0] = wizard1;
|
|
wizards[1] = wizard2;
|
|
}
|
|
|
|
public void execute(int[] bytecode) {
|
|
for (var i = 0; i < bytecode.length; i++) {
|
|
Instruction instruction = Instruction.getInstruction(bytecode[i]);
|
|
switch (instruction) {
|
|
case LITERAL:
|
|
// Read the next byte from the bytecode.
|
|
int value = bytecode[++i];
|
|
// Push the next value to stack
|
|
stack.push(value);
|
|
break;
|
|
case SET_AGILITY:
|
|
var amount = stack.pop();
|
|
var wizard = stack.pop();
|
|
setAgility(wizard, amount);
|
|
break;
|
|
case SET_WISDOM:
|
|
amount = stack.pop();
|
|
wizard = stack.pop();
|
|
setWisdom(wizard, amount);
|
|
break;
|
|
case SET_HEALTH:
|
|
amount = stack.pop();
|
|
wizard = stack.pop();
|
|
setHealth(wizard, amount);
|
|
break;
|
|
case GET_HEALTH:
|
|
wizard = stack.pop();
|
|
stack.push(getHealth(wizard));
|
|
break;
|
|
case GET_AGILITY:
|
|
wizard = stack.pop();
|
|
stack.push(getAgility(wizard));
|
|
break;
|
|
case GET_WISDOM:
|
|
wizard = stack.pop();
|
|
stack.push(getWisdom(wizard));
|
|
break;
|
|
case ADD:
|
|
var a = stack.pop();
|
|
var b = stack.pop();
|
|
stack.push(a + b);
|
|
break;
|
|
case DIVIDE:
|
|
a = stack.pop();
|
|
b = stack.pop();
|
|
stack.push(b / a);
|
|
break;
|
|
case PLAY_SOUND:
|
|
wizard = stack.pop();
|
|
getWizards()[wizard].playSound();
|
|
break;
|
|
case SPAWN_PARTICLES:
|
|
wizard = stack.pop();
|
|
getWizards()[wizard].spawnParticles();
|
|
break;
|
|
default:
|
|
throw new IllegalArgumentException("Invalid instruction value");
|
|
}
|
|
LOGGER.info("Executed " + instruction.name() + ", Stack contains " + getStack());
|
|
}
|
|
}
|
|
|
|
public void setHealth(int wizard, int amount) {
|
|
wizards[wizard].setHealth(amount);
|
|
}
|
|
// other setters ->
|
|
// ...
|
|
}
|
|
```
|
|
|
|
अब हम वर्चुअल मशीन का उपयोग करके पूरा उदाहरण दिखा सकते हैं।
|
|
|
|
```java
|
|
public static void main(String[] args) {
|
|
|
|
var vm = new VirtualMachine(
|
|
new Wizard(45, 7, 11, 0, 0),
|
|
new Wizard(36, 18, 8, 0, 0));
|
|
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("LITERAL 0"));
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("LITERAL 0"));
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("GET_HEALTH"));
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("LITERAL 0"));
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("GET_AGILITY"));
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("LITERAL 0"));
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("GET_WISDOM"));
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("ADD"));
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("LITERAL 2"));
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("DIVIDE"));
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("ADD"));
|
|
vm.execute(InstructionConverterUtil.convertToByteCode("SET_HEALTH"));
|
|
}
|
|
```
|
|
|
|
यहाँ कंसोल आउटपुट है.
|
|
|
|
```
|
|
16:20:10.193 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed LITERAL, Stack contains [0]
|
|
16:20:10.196 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed LITERAL, Stack contains [0, 0]
|
|
16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed GET_HEALTH, Stack contains [0, 45]
|
|
16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed LITERAL, Stack contains [0, 45, 0]
|
|
16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed GET_AGILITY, Stack contains [0, 45, 7]
|
|
16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed LITERAL, Stack contains [0, 45, 7, 0]
|
|
16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed GET_WISDOM, Stack contains [0, 45, 7, 11]
|
|
16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed ADD, Stack contains [0, 45, 18]
|
|
16:20:10.197 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed LITERAL, Stack contains [0, 45, 18, 2]
|
|
16:20:10.198 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed DIVIDE, Stack contains [0, 45, 9]
|
|
16:20:10.198 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed ADD, Stack contains [0, 54]
|
|
16:20:10.198 [main] INFO com.iluwatar.bytecode.VirtualMachine - Executed SET_HEALTH, Stack contains []
|
|
```
|
|
|
|
## क्लास डायग्राम
|
|
|
|

|
|
|
|
## प्रयोज्यता
|
|
|
|
जब आपके पास बहुत सारे व्यवहार हों जिन्हें आपको परिभाषित करने की आवश्यकता हो तो बाइटकोड पैटर्न का उपयोग करें
|
|
गेम की कार्यान्वयन भाषा उपयुक्त नहीं है क्योंकि:
|
|
|
|
* यह बहुत निम्न स्तर का है, जिससे इसे प्रोग्राम करना कठिन या त्रुटि-प्रवण हो जाता है।
|
|
* धीमे संकलन समय या अन्य टूलींग समस्याओं के कारण इस पर पुनरावृत्ति करने में बहुत अधिक समय लगता है।
|
|
* इस पर बहुत ज्यादा भरोसा है. यदि आप यह सुनिश्चित करना चाहते हैं कि परिभाषित किया जा रहा व्यवहार गेम को तोड़ न सके, तो आपको इसे शेष कोडबेस से सैंडबॉक्स करना होगा।
|
|
|
|
## संबंधित पैटर्न
|
|
|
|
* [Interpreter](https://java-design-patterns.com/patterns/interpreter/)
|
|
|
|
## श्रेय
|
|
|
|
* [Game programming patterns](http://gameprogrammingpatterns.com/bytecode.html)
|