แนวคิด (Concepts)

นิยาม

การเขียนโปรแกรมเชิงวัตถุ (Object-Oriented Programming, OOP) เป็นแนวคิดเพื่อออกแบบและเขียนโปรแกรมเพื่อพัฒนาระบบโดย มองลำดับการทำงานของระบบให้เป็นลำดับการสั่งงานระหว่าง สิ่งของ ที่เก็บ ข้อมูล และสามารถ สั่งงาน ได้

  • สิ่งของ ใช้ทับศัพท์ว่า อ็อบเจ็กต์ (Object)

  • สิ่งของ ในระบบเป็นประเภทเดียวกันได้

  • เขียน class เพื่อเป็นพิมพ์เขียวของสิ่งของแต่ละประเภท

  • class จะต้องระบุ ข้อมูล (attributes) และ สั่งงาน (methods)

ที่มาและความสำคัญ

ตัวอย่างการเขียนโปรแกรมเพื่อจัดการข้อมูลเกมเพื่อจัดเก็บข้อมูลพลังชีวิตและพลังโจมตีของผู้เล่น player และ ศัตรู 2 ตัว และในกรณีที่ไม่ใช้การเขียนโปรแกรมเชิงวัตถุสามารถเขียนได้ดังนี้

แบบที่ 1

 1hp = { 'player': 100, 'enemy1': 100, 'enemy2': 100, 'boss': 2000 }
 2attacks = { 'player': 3, 'enemy1': 5, 'enemy2': 10, 'boss': 20 }
 3
 4def attack(a='player', b='boss'):
 5    '''a โจมตี b ทำให้ hp ของ b ลดลง'''
 6    hp[b] -= attacks[a]
 7
 8def player_lose(a='player', b='boss'):
 9    '''ตรวจสถานะของเกมว่าตอนนี้ผู้เล่นแพ้หรือไม่?'''
10    '''แปลว่า? hp ของ player <= 0'''
11    return hp['player'] <= 0
12
13def player_win(a='player', b='boss'):
14    '''ตรวจสถานะของเกมว่าตอนนี้ผู้เล่นชนะหรือไม่?'''
15    '''แปลว่า? hp ของ enemy1 enemy2 และ boss <= 0'''
16    pass # exercise
17
18attack('player', 'enemy1')
19attack('player', 'boss')
20print(hp['enemy1'], hp['boss'])

แบบที่ 2

 1game_data = {
 2    'player': { 'hp':  100, 'attack':  3 },
 3    'enemy1': { 'hp':  100, 'attack':  5 },
 4    'enemy2': { 'hp':  100, 'attack': 10 },
 5    'boss':   { 'hp': 2000, 'attack': 20 },
 6}
 7
 8def attack(a='player', b='boss'):
 9    '''a โจมตี b ทำให้ hp ของ b ลดลง'''
10    game_data[b]['hp'] -= game_data[a]['attack']
11
12def player_lose(a='player', b='boss'):
13    '''ตรวจสถานะของเกมว่าตอนนี้ผู้เล่นแพ้หรือไม่?'''
14    '''แปลว่า? hp ของ player <= 0'''
15    return game_data['player']['hp'] <= 0
16
17def player_win(a='player', b='boss'):
18    '''ตรวจสถานะของเกมว่าตอนนี้ผู้เล่นชนะหรือไม่?'''
19    '''แปลว่า? hp ของ enemy1 enemy2 และ boss <= 0'''
20    pass # exercise
21
22attack('player', 'enemy1')
23attack('player', 'boss')
24print(game_data['enemy1']['hp'], game_data['boss']['hp'])

คำถามน่าคิด?

  • เกมซับซ้อนขึ้นทำให้มีผู้เล่นมากกว่า 1 ศัตรูมากกว่า 100 และหัวหน้ามากกว่า 10 ด่าน การเขียนแต่ละแบบจะมีผลกระทบอย่างไร?

  • เกมซับซ้อนขึ้นทำให้ประเภทข้อมูลที่ต้องจัดเก็บเพิ่มและต้องเขียนฟังก์ชันเพิ่ม เช่นการเพิ่มระบบอาวุธ การป้องกัน แล้วการเขียนแต่ละแบบจะมีผลกระทบอย่างไร?

การเขียนเชิงวัตถุ

 1class Character:
 2    def __init__(self, label, hp, damage):
 3        self.label = label
 4        self.hp = hp
 5        self.damage = damage
 6      
 7    def attack(self, b):
 8        b.hp -= self.damage
 9
10    def __str__(self):
11        return self.label
12
13player = Character('player', 100, 3)
14enemy1 = Character('enemy', 100, 5)
15enemy2 = Character('enemy', 100, 10)
16boss = Character('boss', 2000, 20)
17
18player.attack(enemy1)
19player.attack(boss)
20print(enemy1.hp, boss.hp)

ถ้าต้องการสร้าง __init__ อัตโนมัติสามารถใช้ dataclass ดังนี้

 1from dataclasses import dataclass
 2
 3@dataclass
 4class Character:
 5    label: str
 6    hp: int = 100
 7    damage: int = 3
 8      
 9    def attack(self, b):
10        b.hp -= self.damage
11
12    def __str__(self):
13        return self.label
14
15player = Character('player', 100, 3)
16enemy1 = Character('enemy', 100, 5)
17enemy2 = Character('enemy', 100, 10)
18boss = Character('boss', 2000, 20)
19
20player.attack(enemy1)
21player.attack(boss)
22print(enemy1.hp, boss.hp)