Java#24 แพ็กเกจ คืออะไร ทำไมจึงต้องสร้างขึ้นมา?

แพ็กเกจ (package) ในภาษา Java เราใช้ในการเก็บไฟล์ต่าง ๆ ของโปรแกรม ให้เป็นระเบียบเรียบร้อย ป้องกันการตั้งชื่อไฟล์ซ้ำกัน รวมไปถึงความสามารถ ในการกำหนดการเข้าถึงคลาส ตัวแปร หรือเมธอดต่าง ๆ ด้วย

 

หากมองในมุมของการพัฒนาภาษา Java ร่วมกัน ของคนทั้งโลก แพ็กเกจ คือสิ่งที่เราใช้แบ่งแยกโค้ดของเรา กับโค้ดของคนอื่น ๆ นั่นคือเหตุผลที่เราต้องตั้งชื่อ แพ็กเกจ ให้ไม่ซ้ำกับใครเลยบนโลกใบนี้

 

คำแนะนำในการตั้งชื่อ package คือ การใช้ชื่อโดเมน (domain) หรือชื่อเว็บไชต์ ซึ่งไม่ซ้ำกันยู่แล้ว มาเป็นชื่อ package และเรียงจากด้านหลัง มาด้านหน้า

 

เช่น เว็บไซต์ mystou.com

จะได้ชื่อแพ็กเกจเป็น com.mystou.ชื่อโปรเจ็กต์หลัก.ชื่อโปรเจ็กต์ย่อย.ชื่อย่อย.ชื่อย่อย.ฯลฯ

การตั้งชื่อแพ็กเกจ เราจะตั้งชื่อย่อยลึกลงไปมากเท่าไหร่ก็ได้ ตามต้องการ

 

พื้นฐานเกี่ยวกับ แพ็กเกจ

เมื่อเราเริ่มต้นพัฒนาซอฟต์แวร์ด้วยภาษา Java สิ่งแรกที่เราจะต้องทำก็คือ “สร้างโปรเจ็กต์” หลังจากสร้างโปรเจ็กต์แล้ว เราก็ “สร้างแพ็กเกจ” จากนั้นค่อยสร้างไฟล์ต่าง ๆ เอาไว้ภายใต้ แพ็กเกจ นั้น ๆ

 

นั่นหมายความว่า โปรเจ็กต์ คือสิ่งที่ใหญ่ที่สุด และเก็บทุกอย่างของโปรแกรมเราเอาไว้

แพ็กเกจ อยู่ภายใต้โปรเเจ็กต์

ไฟล์ ต่าง ๆ อยู่ภายใต้แพ็กเกจ

ภาพที่ 1 โปรเจ็กต์ แพ็กเกจ และไฟล์

 

เพื่อให้เห็นภาพมากขึ้น เรามาเขียนโค้ดและเรียนรู้แต่ละเรื่องไปพร้อมกันเลยดีกกว่าค่ะ

 

การสร้าง โปรเจ็กต์

1. เปิดโปรแกรม NetBeans IDE ขึ้นมา ไปที่ File > New Project

ภาพที่ 2 แสดงการเลือก New Project

 

2. เลือก Java > Java Application และคลิกที่ปุ่ม Next

ภาพที่ 3 Java > Java Application > Next

 

3. ตั้งชื่ออพ็กเกจว่า Learn Package ให้ติ๊กถูกที่หน้า Create Main Class ออก และคลิกที่ Finish

ภาพที่ 4 รายละเอียดโปรเจ็กต์

 

4. เราจะได้โปรเจ็กต์ Learn Package ขึ้นมา

ภาพที่ 5 โปรเจ็กต์ที่สร้างขึ้นมาใหม่

 

การสร้าง แพ็กเกจ

1. คลิกขวาที่ Source Packages ไปที่ New > Java Package

ภาพที่ 6 New > Java Package

 

2. ตั้งชื่อแพ็กเกจว่า com.thjava และคลิกที่ปุ่ม “Finish”

ภาพที่ 7 ตั้งชื่อ package

 

3. เราจะได้แพ็กเกจ com.thjava ขึ้นมา

ภาพที่ 8 package ที่สร้างขึ้นมาใหม่

 

หลังจากสร้างโปรเจ็กต์ และสร้างแพ็กเกจ เสร็จแล้ว เราจะสร้างไฟล์เอาไว้ใน แพ็กเกจ กันค่ะ

 

สร้างไฟล์ เก็บไว้ใน แพ็กเกจ

1. คลิกขวาที่ แพ็กเกจ com.thjava ไปที่ New > Java Main Class

ภาพที่ 9 New > Java Main Class

 

2. ตั้งชื่อคลาสว่า Main และคลิกที่ปุ่ม Finish

ภาพที่ 10 รายละเอียดคลาส

 

3. เราจะได้ไฟล์ Main.java ขึ้นมา ซึ่งอยู่ภายใต้ แพ็กเกจ com.thjava

ภาพที่ 11 แสดงไฟล์ Main.java

 

4. ซึ่งมีโค้ดเริ่มต้นภายในดังภาพด้านล่าง

ภาพที่ 12 แสดงโค้ดในคลาส Main

 

ใช้แพ็กเกจ จัดระเบียบไฟล์

สมมติว่า ตอนนี้เรานำรูปแบบการออกแบบโปรแกรม (Design Pattern) แบบ MVC (Model-View-Constroler) มาใช้ในการออกแบบโปรแกรมของเรา หมายความว่า เราจะแบ่งโค้ดออกเป็น 3 ส่วนหลัก ๆ ดังนี้

 

1. Model ใช้เก็บไฟล์ที่เกี่ยวข้องกับ ออบเจ็กต์ของข้อมูล

2. View ใช้เก็บไฟล์ ที่เป็น หน้าจอโปรแกรม

3. Controller ใช้เก็บไฟล์ ที่ทำหน้าที่ควบคุมการทำงานของโปรแกรม

 

เราสามารถสร้างแพ็กเกจทั้ง 3 แพ็กเกจขึ้นมาได้ ตามโครงสร้างของโปรแกรมที่เราจะสร้างขึ้น โดยมีขั้นตอนดังนี้

 

1. คลิกขวาที่แพ็กเกจ com.thjava ไปที่ New > Java Packages

ภาพที่ 13 New > Java Package

 

2. ตั้งชื่อแพ็กเกจ สั่น ๆ ว่า m แทนคำว่า Model และคลิกที่ปุ่ม Finish

ภาพที่ 14 ตั้งชื่อ package

 

3. เราจะได้ แพ็กเกจ com.thjava.m ขึ้นมา

ภาพที่ 15 แสดง package ใหม่ที่สร้างขึ้นมา

 

4. ทำซ้ำขั้นตอนที่ 1 ถึง ขั้นตอนที่ 3 อีกครั้ง เพื่อสร้าง แพ็กเกจ v (View) และ c (Controller) ขึ้นมา ตามลำดับ และจะได้ แพ็กเก็จ ดังภาพที่ 6

ภาพที่ 16 โครงสร้าง package

 

5. เพียงเท่านี้ เราก็จะสามารถสร้างไฟล์ทั้ง 3 ประเภทเก็บไว้ใน แพ็กเกจต่าง ๆ ได้ ตามความต้องการ ทำให้การพัฒนาซอฟต์แวร์ เป็นไปอย่างมีระบบ ระเบียบมากขึ้น

 

ใช้แพ็กเกจ ป้องการการตั้งชื่อซ้ำกัน

สมมตุว่า เรามีทีมพัฒนาซอฟต์แวร์ 2 ทีม ที่ต้องทำงานร่วมกัน ในโปรเจ็กต์เดียวกัน คือทีม a และ ทีม b เราจะรู้ได้อย่างไรว่า ทั้ง 2 ทีม จะไม่สร้างไฟล์ชื่อซ้ำกันขึ้นมา เราสามารถใช้ แพ็กเกจ ในการป้องกันปัญหานี้ได้ ตามขั้นตอนดังนี้

 

1. คลิกขวาที่ แพ็กเกจ com.thjava ไปที่ New > Java Package

ภาพที่ 17 New > Java Package

 

2. ตั้งชื่อ แพ็กเกจ ว่า team.a และคลิกที่ปุ่ม Finish

ภาพที่ 18 รายละเอียด package

 

3. เราจะได้ แพ็กเกจ com.thjava.team.a ขึ้นมา

ภาพที่ 19 แสดง package ที่สร้างขึ้นมาใหม่

 

4. ทำซ้ำขั้นตอนที่ 1 ถึงขั้นตอนที่ 3 อีกครั้ง เพื่อสร้าง แพ็กเกจ ของทีม b ขึ้นมา จะได้ดังภาพด้านล่าง

ภาพที่ 20 แสดง package

 

5. คลิกขวา ที่แพ็กเกจที่ ลงท้ายด้วย team.a ไปที่ New > Java Class

ภาพที่ 21 New > Java Class

 

6. ตั้งชื่อคลาส ว่า Users และคลิกที่ปุ่ม Finish

ภาพที่ 22 รายละเอียดคลาส

 

7. เราจะได้ไฟล์ Users.java ขึ้นมา

ภาพที่ 23 แสดงไฟล์ Users.java

 

8. หากเราพยายามจะสร้างไฟล์ชื่อ Users ขึ้นมาใน แพ็กเกจ ที่ลงท้ายด้วย team.a โปรแกรมจะฟ้องว่า มีไฟล์นี้อยู่ในแพ็กเกจแล้ว ไม่สามารถสร้างไฟล์ที่มีชื่อซ้ำกันได้

ภาพที่ 24 การตั้งชื่อไฟล์ซ้ำกัน

 

9. ลองคลิกขวาที่ แพ็กเกจ ที่ลงท้ายด้วย team.b ไปที่ New > Java Class

ภาพที่ 25 New > Java Class

 

10 ตั้งชื่อ แพ็กเกจ ว่า Users และคลิกที่ปุ่ม Finish

ภาพที่ 26 รายละเอียดคลาส

 

11. จะเห็นว่า เราสามารถสร้างไฟล์ ชื่อเดียวกัน แต่อยู่ต่าง แพ็กเกจ กันได้ เวลาเรียกใช้งาน เราแค่ระบุให้แน่ชัดว่า จะเรียกใช้ไฟล์ Users จาก แพ็กเกจ ใดเพียงเท่านั้น ซึ่งการระบุนั้น เราเรียกว่า การอิมพอร์ท (import)

ภาพที่ 27 แสดงไฟล์ชื่อเดียวกัน อยู่ต่าง package กัน

 

การอิมพอร์ท (import)

การ import คือ การนำไฟล์ที่อยู่ต่าง package มาใช้งานในคลาสที่เรากำลังเขียนโค้ดอยู่ในปัจจุบัน ซึ่งขั้นตอนในการ import มีดังต่อไปนี้

 

1. มาที่ไฟล์ Main.java คลิกในพื้นที่ว่าง ในเมธอด main()

ภาพที่ 28 ไฟล์ Main.java

 

2. สร้างออบเจ็กต์จากคลาส Users ขึ้นมา

ภาพที่ 29 การสร้างออบเจ็กต์

 

3. กดคีย์ลัด Ctrl + Shift + i จะปรากฏหน้าจอ Fix All imports ขึ้นมา ให้คลิกที่ ลูกศร ชี้ลง

ภาพที่ 30 หน้า Fix All Imports

 

4. จะปรากฏรายการแพ็กเกจ ขึ้นมาให้เลือก ว่าเราจะใช้คลาส Users จากแพ็กเกจใด ให้เลือก import คลาส Users จาก แพ็กเกจ a และคลิกที่ปุ่ม OK

ภาพที่ 31 เลือก import คลาสจาก package ที่ลงท้ายด้วย a

 

5. เราจะได้โค้ด import คลาส Users ที่มีเส้นทางไปที่แพ็กเกจที่ลงท้ายด้วยตัว a และโปรแกรมก็ไม่มีข้อผิดพลาดแล้ว

ภาพที่ 32 แสดงคำสั่ง import

 

 

ใช้แพ็กเกจ กำหนดการเข้าถึงตัวแปร

1. มาที่ไฟล์ Users.java ในแพ็กเกจ a คลิกหาพื้นที่ว่าง เตรียมเขียนโค้ด

ภาพที่ 33 เตรียมเขียนโค้ด

 

2. ประกาศตัวแปร ชนิด String ตั้งชื่อว่า name มีการกำหนดการเข้าถึงแบบ public

ภาพที่ 34 ประกาศตัวแปร

 

3. มาที่ไฟล์ Main,java ใช้ obj เรียกใช้ตัวแปร name โดยกำหนดค่าให้เห็บชื่อ “สมใจ” เอาไว้

ภาพที่ 35 กำหนดค่าเริ่มต้นให้ตัวแปร

 

4. กลับมาที่ไฟล์ Users.java ให้ลบคำสั่ง public หน้าตัวแปร name ออก

ภาพที่ 36 ลบ public

 

5. มาที่ไฟล์ Main.java จะเห็นว่า เกิดข้อผิดพลาดขึ้น

ภาพที่ 37 แสดงข้อผิดพลาด

 

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

 

นั่นหมายความว่า การประกาศตัวแปร หรือเมธอด โดยไม่ระบุการเข้าถึง (Access Modifier) จะสามารถเรียกใช้งานได้เฉพาะภายใน package เดียวกันเท่านั้น

ภาพที่ 38 แสดงรายละเอียดข้อผิดพลาด

 

7. กลับไปเพิ่มการกำหนดการเข้าถึงให้ตัวแปร name เป็น public เหมือนเดิม และบันทึกไฟล์ Users.java ให้เรียบร้อย

ภาพที่ 39 การเพิ่ม public

 

ไม่ต้องใช้คำสั่ง import ได้มั้ย?

1. มาที่ไฟล์ Users.java ในแพ็กเกจ team.b คลิกในพื้นที่ว่าง เตรียมเขียนโค้ดเพิ่ม

ภาพที่ 40 เตรียมเขียนโค้ด

 

2. ประกาศตัวแปรชนิด String ตั้งชื่อว่า name กำหนดการเข้าถึงให้เป็นแบบ public

ภาพที่ 41 ประกาศตัวแปร

 

3. มาที่ไฟล์ Main.java เพิ่มคำสั่ง import คลาส Users จากแพ็กเกจ team.b เข้ามา จะเห็นว่า เกิดข้อผิดพลาดขึ้น

ภาพที่ 42 แสดงข้อผิดพลาด

 

4. เมื่อนำเมาส์ไปชี้ที่ เครื่องหมายตกใจสีแดง จะพบว่า เราไม่สามารถ import แพ็กเกจที่มีชื่อคลาสซ้ำกันได้ เพราะเวลาเรียกใช้งาน โปรแกรมจะสับสนว่า เป็นการเรียกใช้ไฟล์ Users จากที่แพ็กเกจไหนกันแน่

ภาพที่ 43 แสดงรายละเอียดข้อผิดพลาด

 

5. ลบคำสั่ง import ทั้ง 2 บรรทัดทิ้งไป และระบุเส้นทางของคลาส Users ที่หน้าชนิดตัวแปรแทน ดังภาพที่ 44

ภาพที่ 44 แสดงการเพิ่มโค้ด

 

6. ลองเรียกใช้คลาส Users จากแพ็กเกจ team.b ด้วยวิธีเดียวกัน จะเห็นว่า เราสามารถเรียกใช้งานคลาส Users จากทั้ง 2 แพ็กเกจได้แล้ว

ภาพที่ 45 แสดงการเพิ่มโค้ด

 

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

 

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

 

จริง ๆ แล้วแพ็กเกจ (package) หากมองง่าย ๆ มันก็ก็คล้าย ๆ โฟลเดอร์ (folder) ที่เราใช้ในชีวิตประจำวัน และในบางครั้ง ในภาษาอื่น ๆ เราอาจจะได้ยินคำศัพท์ เช่น ไลบรารี่ (library), เนมสเปซ (namespace) หรือ คอมโพเนนท์ (component) ซึ่งความหมายของมันก็คือสิ่งที่.ช้จัดเก็บไฟล์ หรือกลุ่มของคลาส หรือ กลุ่มของออบเจ็กต์นั่นเอง