โดย สรพงษ์ เรือนณี เขียนเมื่อ 2543 เผยแพร่เมื่อ 2566

การออกแบบซอฟแวร์ด้วยแนวคิดเชิงวัตถุจะใช้ภาษาโปรแกรมที่มีคุณลักษณะสำคัญ 3 อย่างคือ

1.    Encapsulation          ความสามารถในการปิดบังการทำงานที่สลับซับซ้อนไว้ภายในตัววัตถุและเปิดเผยให้ผู้ใช้วัตถุเห็นเฉพาะส่วนที่จำเป็นสำหรับการใช้งานเท่านั้น[1]

2.    Inheritance              ความสามารถในการขยายต่อ โดยการสร้างคลาสให้สืบทอดต่อจากคลาสแม่ ซึ่งจะทำให้คลาสลูกที่สืบทอดต่อมาได้รับคุณสมบัติทุกอย่างมาจากคลาสแม่ และไม่จำเป็นต้องเขียนโปรแกรมซ้ำกับส่วนที่มีอยู่แล้วในคลาสแม่ ซึ่งถ้าเรานำ Inheritance มาใช้ในรูปแบบที่เหมาะสมจะช่วยทำให้ลดความซ้ำซ้อนในการเขียนโปรแกรมและทำการแก้ไขเปลี่ยนแปลงโปรแกรมได้ง่ายขึ้นอีก

3.    Polymorphism          ความสามารถในการแปรเปลี่ยนการกระทำไปตามชนิดของวัตถุ เราสามารถนำวัตถุที่อยู่ในตระกูลเดียวกัน[2] มาทำงานร่วมกันได้โดยผ่านตัวแปรอ้างอิงเพียงตัวเดียว และใช้การสั่งงานวัตถุที่เหมือนกันตลอดทั้งการทำงาน แต่ตัวแปรอ้างอิงจะย้ายไปอ้างอิงวัตถุที่ต่างชนิดกันและจะมีผลให้เกิดการทำงานที่แตกต่างกันไปตามชนิดของวัตถุที่ตัวแปรอ้างอิงกำลังอ้างถึงอยู่


[1] เราเรียกส่วนที่เปิดเผยให้ผู้ใช้วัตถุเห็นว่า Public Interface

[2] เป็นวัตถุที่ถูกสร้างมาจากคลาสลูกที่สืบทอดมาจากคลาสแม่เดียวกัน หรือเป็นวัตถุที่ถูกสร้างมาจากคลาสที่อิมพลีเมนต์จากอินเตอร์เฟสเดียวกัน

1. การออกแบบเพื่อให้เกิด Encapsulation

ในกรณีที่เราไม่ต้องการให้ไคลเอ็นต์สามารถเข้าถึงค่าที่ใช้ภายในตัววัตถุ เราจะกำหนดระดับการมองเห็น (Visibility) ให้กับแอททริบิวท์นั้นเป็น private ซึ่งแอททริบิวท์ที่มีระดับการมองเห็นเป็น private จะสามารถมองเห็นได้เฉพาะภายในคลาสเดียวกันเท่านั้น คลาสอื่นจะไม่สามารถมองเห็นแอททริบิวท์ที่เป็น private ได้

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

การบังคับให้ไคลเอ็นต์ใช้งานผ่านทาง public เมธอดเสมอ ยังเป็นผลดีคือเมื่อเกิดการเปลี่ยนแปลงวิธีการอิมพลีเมนต์ภายในตัววัตถุโดยที่รูปแบบของเมธอดไม่เปลี่ยน ไคลเอ็นต์จะไม่ได้รับผลกระทบรุนแรงหรืออาจจะไม่จำเป็นต้องแก้ไขโค้ดเลยก็ได้ เนื่องจากไคลเอ็นต์โค้ดไม่ได้ใช้งานแอททริบิวท์ของวัตถุโดยตรงแต่ใช้งานผ่านทางเมธอด ตราบใดที่รูปแบบการเรียกใช้เมธอดไม่เปลี่ยนไปไคลเอ็นต์โค้ดก็ไม่จำเป็นต้องเปลี่ยนแปลงอะไร แม้ว่าภายในตัววัตถุจะมีการเปลี่ยนแปลง อย่างไรบ้างก็ตาม

รูปภาพ 15 แสดงการออกแบบที่ไม่ได้ทำ Encapsulation ที่แอททริบิวท์ id

ตัวอย่างในภาพที่ 15 เราจะเห็นคลาส User ที่ไม่ได้กำหนดให้แอททริบิวท์เป็น private ทำให้ไคลเอ็นต์โค้ดสามารถกำหนดค่าให้กับแอททริบิวท์ได้โดยตรง ซึ่งที่จริงแล้วเราจะไม่ยอมให้ค่า id สามารถเปลี่ยนแปลงได้ ดังนั้นเราจะให้ไคลเอ็นต์สามารถอ่านค่า id ไปดูได้อย่างเดียว แต่ไม่สามารถเปลี่ยนแปลงค่าของ id ได้

รูปภาพ 16 แสดงการออกแบบโดยใช้ Encapsulation ที่แอททริบิวท์ id

ตัวอย่างในภาพที่ 16 จะสังเกตเห็นว่าถ้าเราทำให้แอททริบิวท์ id เป็น private จะมีผลให้ไคลเอ็นต์โค้ดไม่สามารถเข้าถึงแอททริบิวท์ id ได้โดยตรงโดยผ่านทางตัวแปรอ้างอิงเหมือนกับในภาพที่ 15 แต่เราจะจัดให้มีเมธอด getId เพื่อดึงค่าแอททริบิวท์ id ออกไปให้ไคลเอ็นต์นำไปใช้งานต่อ แต่ไคลเอ็นต์โค้ดจะไม่สามารถแก้ไขค่าของ id ได้เนื่องจากเราไม่ได้จัดเตรียมเมธอดอะไรไว้ให้

2.    การออกแบบโดยใช้ Inheritance

เราจะออกแบบคลาสให้สืบทอดต่อจากอีกคลาสหนึ่งก็ต่อเมื่อคลาสทั้งสองคลาสนี้อยู่ในตระกูล (Family) เดียวกัน เมื่อสืบทอดแล้วเราจะเรียกคลาสที่สืบทอดมาว่าคลาสลูก (Sub-Class[1]) และเรียกคลาสที่ถูกสืบทอดต่อไปว่าเป็นคลาสแม่ (Super-Class[2])

รูปภาพ 17 แสดงให้เห็นคลาส Person สืบทอดจากคลาส User

จากภาพที่ 17 เราจะเห็นว่าเมื่อคลาส Person สืบทอดต่อจากคลาส User จะทำให้คลาส Person ได้แอททริบิวท์และเมธอดทุกอย่างของคลาส User ไปด้วย ดังนั้นในภาพนี้เราสรุปได้ว่าคลาส Person มีแอททริบิวท์อยู่ 5 ตัวคือ username และ password ที่ได้รับสืบทอดมาจากคลาส User และแอททริบิวท์ pid firstName และ lastName ที่มีอยู่ในคลาสตัวเอง

การสืบทอดจะแสดงให้เห็นในคลาสไดอะแกรมด้วยเส้น Generalization ซึ่งจะชี้จากคลาสที่เป็นคลาสลูกไปหาคลาสแม่ เนื่องจากหัวลูกศรจะชี้ไปที่คลาสแม่ที่มีความเป็นทั่วไป (General) มากกว่าคลาสลูกดังนั้นจึงเรียกลูกศรนี้ว่า Generalization


[1] สำหรับบางภาษาโปรแกรมอาจจะเรียกแตกต่างกันไปเช่นภาษา C++ เรียกว่า Derived Class

[2] สำหรับบางภาษาโปรแกรมอาจจะเรียกแตกต่างกันไปเช่นภาษา C++ เรียกว่า Base Class

การ Override

เมื่อคลาสลูกสืบทอดต่อมาจากคลาสแม่ คลาสลูกจะได้เมธอดมาจากคลาสแม่ด้วย ทำให้การโปรแกรมที่คลาสลูกไม่จำเป็นต้องเขียนโปรแกรมในส่วนที่คลาสแม่ได้เขียนไว้แล้ว แต่อย่างไรก็ตาม ในบางครั้งถ้าคลาสลูกไม่ต้องการทำงานเช่นเดียวกับที่คลาสแม่เคยทำไว้ เราอาจจะสร้างเมธอดชื่อเดียวกันกับคลาสแม่ไว้ในคลาสลูก แล้วใส่โปรแกรมที่ทำงานแตกต่างไปจากที่คลาสแม่ได้ทำไว้ก็ได้ วิธีดังกล่าวนี้เราเรียกว่า Override[1] และเมธอดที่สร้างขึ้นไว้ในคลาสลูกให้ทับเมธอดในคลาสแม่นี้เราเรียกว่า Overriding Method

รูปภาพ 18 ตัวอย่างการสร้างเมธอดเพื่อทับเมธอดในคลาสแม่

ตัวอย่างในภาพที่ 18 แสดงให้เห็นเมธอด save ในคลาส Person ไม่ได้ใช้กระบวนการ save ที่ได้รับมาจากคลาส User แต่สร้างเมธอด save เป็นของตัวเองแล้วมีกระบวนการ save ที่แตกต่างกันออกไปจากที่คลาสแม่ทำไว้


[1] หนังสือบางเล่มใช้คำว่า Hook หรือคำว่า Subclassing

3.    Polymorphism

เป็นวิธีการที่ช่วยให้โปรแกรมสามารถทำงานได้หลาย ๆ  แบบ โดยใช้วิธีการเขียนโปรแกรมแบบเดียวกัน วิธีการของ Polymorphism มักจะนำมาใช้ในกรณีที่มีวัตถุหลายชนิด และวัตถุแต่ละชนิดมีรูปแบบการสั่งงานเหมือนกันและมีวิธีการทำงานแตกต่างกันไป

ตัวอย่างเช่นในรูปที่ 18 เราจะเห็นว่าถ้าเรานำคลาส User และคลาส Person มาสร้างเป็นวัตถุแล้ว เราจะสามารถสั่งให้วัตถุทั้งสองชนิดนี้บันทึกข้อมูลเก็บไว้ในระบบได้โดยสั่งผ่านทางเมธอด save() ซึ่งจะมีรูปแบบการสั่งงานเหมือนกันคือคำว่า save() แต่การทำงานของวัตถุทั้งสองชนิดนี้แตกต่างกัน วัตถุ User จะบันทึกข้อมูลเฉพาะ username และ password แต่วัตถุ person จะบันทึกข้อมูลทั้ง username password firstName lastName และ pid ด้วย

รูปภาพ 19 ตัวอย่างการสืบทอดแล้วโอเวอร์ไรด์เมธอด getArea()

จากภาพที่ 19 เราจะเห็นว่าคลาส Circle Rectangle และ Triangle ต่างก็สืบทอดมาจากคลาสแม่ Shape และได้สร้างเมธอดชื่อ getArea() ทับเมธอด getArea() ในคลาสแม่ เนื่องจากวิธีการคำนวณพื้นที่ของรูปร่างแต่ละแบบใช้สูตรคำนวณไม่เหมือนกัน แต่มีรูปแบบการเรียกใช้คำสั่งเป็นแบบเดียวกันคือ เมื่อไคลเอ็นต์โค้ดต้องการทราบพื้นที่ของวัตถุรูปร่างใดก็ตาม ไคลเอ็นต์โค้ดจะเรียกใช้เมธอด getArea() เหมือนกันทั้งหมด

ด้วยวิธีการออกแบบเช่นนี้ ถ้าสมมุติว่าเราต้องคำนวณหาพื้นที่รวมของวัตถุรูปร่างทุกวัตถุที่อยู่ในระบบ เราจะสามารถทำได้ด้วยการเรียกเมธอด getArea() แล้วนำค่าพื้นที่ที่ได้มารวมไว้ในพื้นที่ทั้งหมด

รูปภาพ 20 ตัวอย่างการใช้ Heterogenous Collection[1] กับ Polymorhism


[1] Heterogenous Collection หมายถึงคอลเลคชันที่เก็บวัตถุที่ต่างชนิดกัน แต่อยู่ในตระกูลเดียวกัน

จากภาพที่ 20 จะเห็นว่าเราสามารถนำวัตถุที่อยู่ในตระกูลเดียวกันมาวางไว้ในคอลเลคชันเดียวกัน เพื่อให้เกิดเป็น Heterogenous Collection แล้วเราสามารถใช้คำสั่งเพียงคำสั่งเดียวเพื่อเรียกใช้เมธอด getArea ของวัตถุทั้งหมด ขณะที่เรียกใช้เมธอด getArea จะไปเรียกใช้เมธอดของคลาสที่ตรงกับชนิดของวัตถุตัวนั้นโดยอัตโนมัติ[1]

รหัสโปรแกรม – 1 ตัวอย่างไคลเอ็นต์โค้ดที่เขียนแบบ Polymorphism

จากรหัสโปรแกรม 1 เราจะสามารถเขียนเรียกใช้เมธอด getArea() ได้เหมือนกันทุกรอบของการทำงานในลูป โดยในขณะที่รันโปรแกรมจริง ๆ  จะไปเรียกใช้เมธอด getArea() ของคลาสไหน จะขึ้นอยู่กับชนิดของวัตถุว่าถูกสร้างขึ้นมาจากคลาส Circle Triangle หรือ Rectangle และจะใช้สูตรการคำนวณพื้นที่ที่เป็นของวัตถุชนิดนั้น ๆ  เอง


[1] เรียกว่า Virtual Method Invocation

รหัสโปรแกรม – 2 ตัวอย่างไคลเอ็นต์โค้ดที่เขียนโดยไม่ใช้ Polymorphism

ในรหัสโปรแกรม 2 เราจะสังเกตเห็นว่าถ้าไม่ใช้วิธีการแบบ Polymorphism เราจะต้องเขียนโปรแกรมเพื่อตรวจสอบก่อนว่าวัตถุมีชนิดเป็นอะไร แล้วจึงเรียกใช้เมธอดที่มีเฉพาะในวัตถุชนิดนั้น ๆ ซึ่งเป็นวิธีการที่ไม่สะดวกเนื่องจากมีลักษณะที่จำเพาะเจาะจงเกินไป แล้วทำให้ต้องเขียนโปรแกรมมากขึ้นเรื่อย ๆ  ถ้ามีวัตถุหลากหลายชนิดขึ้นอีก

การแบ่งแยกคุณลักษณะพื้นฐานออกจากคุณลักษณะพิเศษ (Abstraction)

ในการพัฒนาระบบงานที่สลับซับซ้อน เราจะมีวัตถุหลากหลายชนิด ซึ่งแต่ละวัตถุก็จะมีคุณลักษณะที่ซ้ำซ้อนกัน และมีคุณลักษณะที่พิเศษเป็นของตัววัตถุชนิดนั้น ๆ  เอง ในกรณีที่เราต้องการจะนำระบบเดิมกลับมาใช้ใหม่โดยให้มีการแก้ไขน้อยที่สุด[1] เราจำเป็นต้องออกแบบระบบโดยแบ่งแยกระดับ (Layer) ออกเป็นสองระดับคือ

1.    ส่วนเฟรมเวิร์ค (Framework) เป็นส่วนที่รวบรวมเอาคุณลักษณะพื้นฐานของระบบไว้ แม้ว่าจะมีการเปลี่ยนแปลงสภาวะแวดล้อมหรือความต้องการของผู้ใช้เปลี่ยนไป ส่วนเฟรมเวิร์คนี้จะไม่มีการเปลี่ยนแปลง[2] หรือถ้ามีการเปลี่ยนแปลงก็น้อยมาก บางครั้งเราเรียกส่วนนี้ว่าส่วน Generic

2.    ส่วนแอพพลิเคชัน (Application) เป็นส่วนที่เปลี่ยนแปลงไปตามสภาวะและความต้องการของผู้ใช้โดยขยายการทำงานต่อจากกรอบที่เฟรมเวิร์คได้วางไว้แล้ว เนื่องจากโครงสร้างพื้นฐานต่าง ๆ  จะถูกกำหนดไว้แล้วในระดับเฟรมเวิร์คทำให้การพัฒนาระบบต่อจากเฟรมเวิร์คจะสามารถขึ้นรูประบบได้อย่างรวดเร็วและลดจุดบกพร่องต่าง ๆ  ไปได้เป็นจำนวนมากเนื่องจากจุดบกพร่องส่วนใหญ่จะถูกขจัดออกไปตั้งแต่ตอนพัฒนาเฟรมเวิร์คแล้ว

การพัฒนาเฟรมเวิร์คและแอพพลิเคชันจำเป็นต้องใช้ความสามารถของภาษาโปรแกรมเชิงวัตถุอีกสองอย่างคือ

1.    แอบส์แทรค (Abstract) การออกแบบส่วนนามธรรม

2.    อินเตอร์เฟส (Interface) การออกแบบความสามารถของวัตถุ

1. แอบส์แทรค (Abstract)

การออกแบบคลาสให้เป็นแอบส์แทรคคลาส (Abstract Class) จะมีผลบังคับให้ไคลเอ็นต์โค้ดไม่สามารถนำแอบส์แทรคไปสร้างเป็นวัตถุได้เหมือนกับคลาสปกติ แต่โปรแกรมเมอร์ที่นำแอบส์แทรคคลาสมาใช้จะถูกบังคับให้ต้องสร้างคลาสสืบทอดต่อจากแอบส์แทรคคลาสแล้วจึงนำคลาสลูกไปใช้สร้างเป็นวัตถุได้

เราอาจจะคิดได้อีกอย่างว่าแอบส์แทรคคลาสคือคลาสที่ยังไม่สมบูรณ์ แต่มีวัตถุประสงค์เพื่อใช้เป็นคลาสแม่เท่านั้น โดยในแอบส์แทรคคลาสจะกำหนดโครงสร้างว่าวัตถุชนิดนี้ควรจะมีแอททริบิวท์และเมธอดอะไรอยู่บ้าง เพื่อบังคับให้คลาสลูกที่สืบทอดไปต้องยึดตามโครงสร้างที่แอบส์แทรคคลาสได้กำหนดเอาไว้

รูปภาพ 21 การสืบทอดต่อจากแอบส์แทรคคลาส

จากภาพที่ 21 จะพบว่าคลาส Shape เป็นแอบส์แทรคคลาส และเมธอด getArea เป็นแอบส์แทรคเมธอด ใน UML จะเขียนเป็นอักษรตัวเอน คลาสลูกที่สืบทอดต่อจากคลาส Shape จะถูกบังคับว่าต้องทำเมธอด getArea ให้สมบูรณ์ จึงจะสามารถคอมไพล์ผ่านไปได้ ตัวอย่างเช่นคลาสลูก Circle และคลาส Rectangle จะต้องสร้างเมธอด getArea ที่สมบูรณ์ไว้ สำหรับคลาส Triangle ในภาพที่ 21 ถ้าไม่ต้องการสร้างเมธอด getArea จะทำให้คลาส Triangle คอมไพล์ไม่ผ่านหรือไม่ก็จะทำให้คลาส Triangle ต้องกลายสภาพเป็นแอบส์แทรคไปด้วย

การใช้แอบส์แทรคจะช่วยในการออกแบบโครงสร้างเฟรมเวิร์คโดยในเฟรมเวิร์คจะกำหนดคลาสไว้เป็นแอบส์แทรคคลาส และดำเนินการในส่วนที่เป็นปฏิบัติการขั้นพื้นฐานเตรียมไว้ให้ เมื่อคลาสลูกที่ระดับแอพพลิเคชันสืบทอดต่อมาจากคลาสแม่ที่เป็นแอบส์แทรคคลาสคลาสลูกจะต้องเพิ่มปฏิบัติการพิเศษที่เป็นรายละเอียดเฉพาะในแต่ละระบบงานใส่เข้าไปเองอีกทีให้สมบูรณ์


[1] หัวใจสำคัญที่สุดของ Reusable Software Design คือ Minimize Change

[2] ในทางอุดมคติ เฟรมเวิร์คควรจะสามารถนำไปประยุกต์ใช้ได้กับทุกๆระบบที่อยู่ในโดเมน (Domain) เดียวกัน

2. อินเตอร์เฟส (Interface)

อินเตอร์เฟสใช้สำหรับเป็นข้อตกลงระหว่างไคลเอ็นต์โค้ดและอิมพลีเมนต์โค้ด[1] เพื่อให้โปรแกรมเมอร์ที่นำวัตถุไปใช้งานสามารถใช้งานได้ตามข้อตกลงที่ทำกันไว้ตั้งแต่แรก โดยที่โปรแกรมเมอร์ที่เขียนไคลเอ็นต์โค้ดไม่จำเป็นต้องรู้ว่าวัตถุที่ทำงานให้จริง ๆ  นั้นเป็นวัตถุของคลาสอะไร เนื่องจากไคลเอ็นต์โค้ดจะเรียกใช้งานวัตถุผ่านทางอินเตอร์เฟสเสมอ

อินเตอร์เฟสมีความสำคัญอย่างมากสำหรับการพัฒนา API (Application Programming Interface) หรือการพัฒนา Design Specification เพื่อใช้สำหรับแบ่งงานกันทำระหว่างโปรแกรมเมอร์ผู้สร้างวัตถุ และโปรแกรมเมอร์ผู้เรียกใช้วัตถุ ให้สามารถทำงานไปได้พร้อม ๆ  กัน และทำให้สถาปนิกซอฟแวร์สามารถแบ่งแยกระบบงานออกเป็นระบบย่อย ๆ  ได้โดยสะดวกขึ้น

รูปภาพ 22 ตัวอย่างการใช้อินเตอร์เฟสเพื่อออกแบบส่วนตรวจสอบผู้ใช้

จากภาพที่ 22 จะเห็นว่าวัตถุ LoginForm จะรับชื่อผู้ใช้ (Username) และรหัสผ่าน (Password) มาจากผู้ใช้แล้วนำมาตรวจสอบว่าเป็นผู้ใช้ที่ถูกต้องของระบบหรือไม่โดยเรียกใช้เมธอด isValidUser จากอินเตอร์เฟส Authenticator ในกรณีที่เก็บรายชื่อผู้ใช้อยู่ในไดเร็คทอรีเซอร์วิสอย่างเช่น LDAP เราจะใช้อิมพลีเมนต์คลาสเป็น LDAPAuthenticator เพื่อให้นำชื่อผู้ใช้และรหัสผ่านไปตรวจสอบกับไดเร็คทอรี แต่ถ้าในกรณีที่รายชื่อผู้ใช้เก็บอยู่ในฐานข้อมูลเราจะใช้อิมพลีเมนต์คลาสเป็น DatabaseAuthenticator เพื่อให้นำชื่อผู้ใช้และรหัสผ่านไปคิวรีกับตารางในฐานข้อมูล

อย่างไรก็ตามไม่ว่าจะเป็นการใช้อิมพลีเมนต์คลาสตัวไหน ไคลเอ็นต์โค้ดของเรายังคงเขียนโปรแกรมเหมือนเดิมโดยเรียกใช้ผ่านตัวแปรอ้างอิงที่มีชนิดข้อมูลเป็น Authenticator โดยไม่ต้องสนใจว่าอิมพลีเมนต์คลาสที่ทำงานให้จริง ๆ  คือวัตถุ LDAPAuthenticator หรือวัตถุ DatabaseAuthenticator


[1] อิมพลีเมนต์โค้ด คือโค้ดส่วนที่อยู่ในตัววัตถุ เช่นโค้ดในเมธอด ที่รับผิดชอบทำงานให้ตามหน้าที่ที่ได้รับมอบหมาย

จากวิธีการดังที่กล่าวมานี้ถ้าเรานำอินเตอร์เฟสมาใช้ได้อย่างถูกต้องเหมาะสมจะทำให้เราได้ Pluggable Software ที่สามารถถอดประกอบชิ้นส่วนบางส่วนเข้าหรือออกได้ตลอดเวลา เมื่อเรานำส่วนประกอบต่อเข้าไปจะทำให้ระบบงานมีความสามารถพิเศษเพิ่มเติมตามที่ผู้ใช้ต้องการ และเมื่อเรานำส่วนประกอบถอดออกมาก็จะทำให้ระบบงานทำงานตามค่าปกติที่ได้ตั้งไว้

ใน UML จะเขียนอินเตอร์เฟสด้วยสัญลักษณ์สองแบบคือเขียนเป็นรูปสี่เหลี่ยมแล้วหมายเหตุไว้ด้วยสเตอริโอไทป์ว่า interface อย่างเช่นในภาพที่ 22 หรือเขียนเป็นสัญลักษณ์รูปวงกลมอย่างเช่นในภาพที่ 23 ก็ได้

รูปภาพ 23 แสดงการเขียนอินเตอร์เฟสแบบ Short-form

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *