ความหมายของ Verification และ Validation

ในการทำ Software Testing จะใช้คำสองคำนี้พร้อมๆกัน อาจเป็นเพราะแยกไม่ออกว่าอันไหนเป็น Verification อันไหนเป็น Validation ซึ่งถ้าเราดูใน CMMI-Dev จะแบ่งแยกออกเป็น 2 Processarea  หมายถึงมี processes(กลุ่มของ process) 2 กลุ่ม ซึ่งใน 2 กลุ่มนี้จะมีหน้าที่ต่างกัน

Verification จะตั้งคำถามว่า

Are we building the product right?

ส่วน Validation กลับตั้งคำถามว่า

Are we building the right product?

นั่นหมายความว่า Verification จะต้องการ product ที่ถูกต้องตาม Requirement และ design เนื่องจากกระบวนการในการทำ Verification(ขั้นตอนการ review รูปแบบต่างๆ) จะเน้นที่การ remove defect ออกตั้งแต่ phase แรกๆ เพื่อที่จะ effort ในการทำ testing ลง

ส่วน Validation จะหมายถึงการทดสอบ product ว่าตรงกับ business requirement หรือไม่(ไม่ใช่ Software Requirement นะครับ) พูดง่ายๆว่า Software ที่เราได้นั้นตรงกับสิ่งที่ลูกค้าต้องการหรือไม่ และสามารถใช้งานได้จริง

และความแตกต่างที่เห็นได้ชัดอีกอย่างหนึ่งก็คือ Verification จะเน้นที่การตรวจสอบ Work product(สิ่งที่เกิดขึ้นระหว่างกระบวนการแต่ไม่ใช่สิ่งที่เอาไปใช้งานจริง) แต่ส่วน Validation จะตรวจสอบที่ Product(Software ที่เราผลิดขึ้นมา) เป็นหลัก

ดังนั้นในการทำ Software Testing จำเป็นจะต้องทำทั้ง 2 กลุ่มนี้ ซึ่งอาจทำมากหรือทำน้อยให้พิจารณาจากขนาดและความซับซ้อนของ Project

สุดท้ายในการทำ Verfication และ Validation มีอีกหลายกระบวนการข้างในอีกมากมาย ซึ่งเราต้องจะนำมาพูดถึงในโอกาสต่อไป

การผลิตซอฟต์แวร์ที่มีคุณภาพแพงกว่าจริงเหรอ

ถ้าพูดถึงเรื่องต้นทุนในการผลิตซอฟต์แวร์ เรามักจะนึกถึงค่าจ้าง programmer มานั่งเขียน Code ให้เรา ถ้าถึงเวลางานที่ได้เป็นไปตามเป้าหมายที่เราต้องการนั่นก็เป็นเรื่องที่ดี แต่ถ้าไม่ก็ต้องหาทางกดดันให้ได้ผลลัพธ์ที่ต้องการไม่ว่าด้วยวิธีการยังไงก็ตาม ปัญหาเกิดจากการ (under estimate) หรือการประเมินราคาออกมาต่ำเกินไปนั่นเอง

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

ซึ่งโดยต้นทุนของการคำนวนเรื่องของต้นทุน เราจะพูดถึงค่า Cost of Quality (COQ) ซึ่ง COQ จะมีสมการดังนี้

ซึ่งค่าของค่าของ Cost ทั้งสองตัวมีความหมาย ดังนี้

  • Appraisal Cost คือต้นทุนในการป้องกันปัญหา ไม่ให้เกิด
  • Failure Cost คือต้นทุนที่ทำการแก้ไขหลังจากเกิดปัญหาขึ้นมาแล้ว

คือทั้งสองตัวนี้จะเป็นต้นทุนในการแก้ปัญหาเหมือนกัน แต่ทั้ง 2 ตัวนี้จะทำก่อนเกิดปัญหาและหลังจากเกิดปัญหา ซึ่งวิธีในการป้องกันปัญหามีหลายวิธี เช่นการทำ Code Review หรือ Design Review (ในกระบวนการของการ Review ก็มีให้เลือกหลายวิธีด้วยกัน)

แต่เราจะทำการวิเคาระห์จากสมการนี้กันว่าจริงๆแล้วการผลิตซอฟต์แวร์ที่มีคุณภาพสูงนั้นต้องมีต้นทุนที่สูงจริงหรือไม่

เริ่มจากการทำความเข้าใจธรรมชาติของการผลิตซอฟต์แวร์  ต้นทุนของการแก้ไขข้อผิดพลาดหรือ จัดการกับ Bug นั้นจะสูงขึ้นเมื่อเวลาผ่านไป ยิ่งผ่านไปแต่ละ Phase ต้นทุนก็จะยิ่งสูงขึ้นเรื่อยๆ ดังนั้นต้นทุนในการ Fix Bug จะสูงที่สุดเมื่ออยู่ใน Operation หรือเอาไปใช้งานจริงเรียบร้อยแล้ว

ดังนั้น ถ้าเราเอาต้นทุนที่คิดจากเวลาของทีมงานที่ใช้ในการป้องกันปัญหา เช่น จากเดิมเราไม่เคยทำการ Review เลย เราต้องเสียเวลาของคนในทีม แทนที่จะได้เขียน code แต่ต้องมานั่งอ่าน Code ของเพื่อนแทน

ซึ่งเราจะเทียบง่ายๆว่า ถ้าเวลาในการอ่าน Code ของเพื่อน 1 ชั่วโมง กับเวลาที่เราใช้ในการจัดการ Bug ของเราเอง อันไหนน่าจะได้ผลงานมากกว่า ซึ่งในงานวิจัยโดยส่วนใหญ่เราจะพบว่าในเวลา 1 ชั่วโมงที่เสียไป กับการ review จะทำให้ Defect หรือ Bug ที่เกิดขึ้นลดลงอย่างเห็นได้ชัด เนื่องจากจะได้ Code ที่เขียนจาก 2 มุมมองคือ เจ้าของ Code และคน Review

ดังนั้นการที่เราทำการเสียเวลา ทำการ Reviewใน Phase ต้นๆ นั้นจะลดภาระใน Testing ไปได้เยอะ เราจึงสรุปได้ว่า การที่เราจะผลิตซอฟต์แวร์ที่มีคุณภาพที่สูงนั้น ไม่ได้มีต้นทุนที่สูงกว่าเสมอไป ขึ้นอยู่กับกระบวนการผลิตของแต่ละองค์กร ดังนั้นเราสามารถที่จะเพิ่ม Quality และลดต้นทุนได้พร้อมๆ กัน เรียกได้ว่ายิงปืนนัดเดียวได้นกสองตัวเลยทีเดียว

 

Coding standards กับ Naming conventions ความเหมือนที่แตกต่าง

คำว่า Coding Standards และ Naming Conventions จะเป็นคำที่พูดถึงกันบ่อยๆ ใน Software Engineer แต่สิ่งที่คนมักจะใช้ผิดคือความหมายของ 2 คำนี้ที่ใกล้กัน จริงๆแล้ว Naming Conventions จะเป็นส่วนหนึ่งใน Coding Standards  ดังนั้นถ้าพูดถึง Naming Conventions จะเป็นการพูดถึงส่วนหนึ่งของ Conding Standards

Naming Conventions หมายถึงรูปแบบของการตั้งชื่อตัวแปร เป็นบทแรกๆใน Conding Standards แต่ Coding Standards ไม่ได้มีเพียงแค่ Naming Conventions เท่านั้น แต่ยังรวมไปถึง เรื่องอื่นๆด้วย เช่น Overload Method , Exception Handling และอื่นๆ

Overload Method เป็นส่วนที่จะกำหนดว่า Method ใดบ้างที่มีการ Overload และ Parameter มีกี่รูปแบบอะไรบ้าง (ใน PHP ไม่จำเป็นต้องมีเอกสารส่วนนี้เนื่องจากการทำ Overload ใน PHP นั้นทำได้แค่กำหนดให้ parameter นั้นเป็น optional)

Exception Handling เป็นส่วนที่ทำการกำหนดว่าในการเกิด Exception จากสาเหตุต่างๆนั้น เราจะ handle(parameter ที่กำหนดใน catch) ด้วย Exception ตัวไหน หรือ ในกรณีที่เราจะโยน(throw) Exception ตัวไหนออกไป  และถ้าเราต้องสร้าง Exception ขึ้นมาเอง Exception ตัวนั้นจะสื่อความหมายถึงอะไร เช่น EmptyException หมายถึง ไม่มีข้อมูลในฐานข้อมูล เป็นต้น

Coding Standards จะเป็นเอกสารที่พูดถึงรูปแบบของการเขียน Code ทั้งหมด ซึ่งรวมทั้งการตั้งชื่อใน Naming Conventions ซึ่งประโยชน์ของการมี Coding Standard นอกจากจะทำให้ Source Code ของเราอ่านง่ายขึ้นแล้วยังมีผลทำให้เรายังสามารถที่จะวัดขนาดของ Software ง่ายขึ้นอีกด้วย เนื่องจากรูปแบบของการเขียน code นั้นถูกกำหนดไว้อย่างชัดเจน

Coding Standards จะเป็นจุดเริ่มต้นที่ดีของการทำ SPI (Software Process Improvement) เพราะถ้าองค์กรไหนขาด Coding Standards หรือ มี Coding Standards แต่ Programmer ในทีมไม่เอาไปใช้งาน ไม่ว่าจะทำอย่างไร Software ของเราก็ไม่มีทางที่จะคุณภาพ

หลักการเขียนโปรแกรม ตอนที่ 5

ในบทความนี้นจะต่อเรื่องจากบทความที่แล้วในเรื่องของ low coupling ในตอนนี้จะเป็นเรื่องของ high cohesion ก่อนอื่นเราต้องทำความเข้าใจเรื่องของ cohesion กันก่อน คำว่า cohesion แปลว่าเนื้อเดียวกัน หรือ การทำงานร่วมกัน ดังนั้นถ้าพูดถึงในเชิงของ Software Engineer เราจะใช้ค่า cohesion เป็นมาตรวัด ถ้าค่า codesion สูงๆ หมายถึง code นั้น reusability และ readability ที่สูง

Cohesion จะเพิ่มขึ้นถ้า

  • เราสร้าง class แล้วให้เรียกใช้ function ผ่าน method ของ class นั้น
  • 1 class ต้องมีจุดประสงค์เพื่อทำงานอย่างใด อย่างหนึ่งเท่านั้น อย่าทำหลายอย่าง
  • method แต่ละ method ต้องทำงานให้น้อยที่สุด อย่าให้ 1 method ทำงานหลายอย่าง

ข้อดีของการทำให้ระบบของเรามี high cohesion

  • ลดความซับซ้อนของแต่ละ module ลง
  • ทำให้ระบบสามารถแก้ไขได้ง่ายขึ้น
  • เพิ่มค่า reusability ที่สูง

การเพิ่มค่า Cohesion อย่างง่ายๆคือ การเขียนโปรแกรมแบบ Object Oriented และใช้แนวคิด Seperation of Concern

หลักการเขียนโปรแกรม ตอนที่ 4

ในการเขียนโปรแกรม เราต้องรู้จักหลักการที่สำคัญอีกตัวนึงคือ Low coupling และ High cohesion ในบทความนี้เราจะพูดถึงในส่วนแรก คือ Low coupling

ก่อนอื่นมาทำความรู้จักกับ คำว่า Coupling กันก่อน Coupling หมายถึงการเชื่อมต่อ นั่นหมายความว่า การที่เกิด coupling เยอะๆ ในระบบ ของเราจะทำให้ code ติดกันเป็นก้อน เวลาทำการย้าย หรือ แก้ไขก็ทำได้ลำบาก เพราะ แต่เมื่อทำการแก้ไขส่วนใดส่วนหนึ่งก็จะกระทบกับส่วนอื่นๆที่เกี่ยวข้อง ดังนั้นการตามไปแก้ไขจะทำได้ยาก

ลักษณะของ Coupling มีอยู่ 2 ประเภทคือ

  • low Coupling หรือ loosely Coupled (แต่ละ module เป็นอิสระ ไม่ขึ้นต่อกัน)
  • high Coupling หรือ tightly Coupled (แต่ละ module จะผูกติดกันเป็นก้อน)

ประเภทของการ Coupling ที่เป็นแบบ Procedural มีดังนี้

  • Content Coupling – เกิดจากการไปทำการ access local data(เช่นตัวแปร) ของ module อื่นๆ
  • Common Coupling – เกิดจาก 2 module เรียก global variable ตัวเดียวกัน
  • External Coupling – เกิดจาก 2 module มีการ export output ในรูปแบบเดียวกัน (เวลาแก้ต้องแก้ทั้ง 2 ที่)
  • Control Coupling -เกิดจาก module นึงทำการควบคุมอีก module นึง
  • Stamp Coupling – เกิดจากการ share composite data structure
  • Data Coupling – เป็น coupling ที่เกิดจากการส่ง parameter
  • Message Coupling (low) – ถ้าจำเป็นจะต้องเกิด coupling ต้องเป็นประเภทนี้ ใช้การส่ง message หากัน

ประเภทของการ Coupling ที่เป็นแบบ Object Oriented (OOP) มีดังนี้

  • Subclass Coupling – เกิดจากการ Inheritance ซึ่งเป็นความสัมพันธ์ที่ควรจะมีให้น้อยที่สุด
  • Temporal Coupling – เกิดจากมี 2 action ทำงานใน module เดียวกัน

วิธีการทำให้เกิด low coupling หรือ เรียกว่าการ decoupling ทำได้หลายวิธี ต้องทำการศึกษาในรายละเอียดของแนวคิดแต่ละแบบ แต่โดยส่วนมากให้ยึดแนวทางตาม Design Pattern เป็นหลักจะดีที่สุด

 

หลักการเขียนโปรแกรม ตอนที่ 3

การเขียนโปรแกรมที่ดีควรจะมีการทำ Coding Standard หมายถึงเอกสารที่เป็นข้อตกลงร่วมกันของคนในทีมพัฒนา เป็นแนวทางหรือรูปแบบในการเขียนโปรแกรม ไม่ว่าจะเป็นรูปแบบการประกาศตัวแปร หรือ การกำหนดโครงสร้างของ if-else รายละเอียดทุกอย่างในการเขียน Code จะอยู่ในเอกสารชุดนี้

แน่นอนว่าเราต้องมีการตรวจสอบอย่างสม่ำเสมอ ว่าในทีมพัฒนาได้มีการนำข้อกำหนดตัวนี้ไปใช้หรือไม่ ไม่เช่นนั้นก็จะกลายเป็นแค่เศษกระดาษชุดนึงเท่านั้นเอง

ตัวอย่าง Coding Standard ที่ใช้โดยทั่วไป

  • ชื่อ Class ต้องนำหน้าด้วยตัวใหญ่เสมอ
  • ชื่อ function และ ชื่อ Class จะเป็น CamelCase (แต่ละคำจะขึ้นต้นด้วยตัวใหญ่ เช่น PowertPivot, iPhone, getName เป็นต้น)
  • ใช้ 1 tab = 4 space
  • การตั้งชื่อตัวแปรที่เป็น Array หรือ Collection อื่นๆ เป็น พหูพจน์ ส่วนตัวแปรอื่นๆจะตั้งชื่อเป็นเอกพจน์

รูปแบบของการตรวจสอบอาจใช้การทำ Code Review  ซึ่งการทำ Code Review มีหลายรูปแบบด้วยกัน การ Review ที่ง่ายที่สุดจะเป็นการใช้ Peer Review คือให้คนในทีมที่ level ใกล้ๆกัน ทำการแลกกัน Review ก็จะเป็นการตรวจสอบการนำ Conding Standard ไปใช้ที่ง่ายที่สุด

นอกจากการ Review จะมีประโยชน์ในเรื่องของการตรวจสอบรูปแบบของ Code ให้เป็นไปตาม Conding Standard ยังได้ในเรื่องของการลด Defect หรือ ข้อผิดพลาดที่เกิดขึ้นลงได้ด้วย

หลักการเขียนโปรแกรม ตอนที่ 2

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

ในการเขียนโปรแกรมก็เหมือนกัน เราต้องทำการจัดการ Source Code ของเราให้เหมือนกับการจัดการหนังสือในห้องสมุด เราต้องทำการแบ่งแยก Source Code ของเราออกเป็นหมวดหมู่หรือเป็นเรื่องๆ

ซึ่งหลักการนี้เรียกว่า Separation of Concern (SoC) หลักการนี้จะนำไปสู่หลักการเขียนโปรแกรมต่างๆมากมาย ไม่ว่าจะเป็น Object Oriented Programming (OOP) หรือ จะเป็น Architecture Pattern ชื่อดังอย่าง MVC ก็ล้วนแล้วแต่เกิดขึ้นมาเพื่อตอบสนองหลักการนี้ทั้งสิ้น

ในการนำหลักการนี้ไปทำการ Implement นั้นก็ต้องใช้แนวคิดหรือ Design Pattern ต่างๆ

  • Object Oriented (OOP)
  • Aspect Oriented Programming (AOP)
  • MVC
  • MVP
  • MVVM
  • Service Oriented Architecture (SOA)
  • และอื่นๆ

ขึ้นอยู่กับว่าเราต้องการแยกส่วนประกอบต่างๆออกมาละเอียดขนาดไหน ซึ่งแต่ละตัวเราจะทำการพูดถึงในบทความตอนต่อๆไป

แต่ที่นำหลักการนี้มาไว้ในบทความตอนแรกๆ เนื่องจากเป็นหลักการที่สำคัญ ก่อนที่เราจะเรียนรู้ OOP เราต้องเรียนรู้หลักการนี้ก่อน ไม่งั้นเราจะใช้ Syntax แบบ OOP แต่เราไม่ได้ใช้วิธีการคิดแบบ OOP เลย เพราะ OOP เป็นการ Speration Code ออกจากกันโดยแยกเรื่องที่ไม่เกี่ยวข้องกันออกจากกัน (เนื่องจาก คำว่า Class ใน OOP ย่อมาจาก คำว่า Classify หรือ Classification)

หลักการเขียนโปรแกรม ตอนที่ 1

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

การเขียน Code แบบนี้ถือว่าเป็น Code ที่ไม่ค่อยมีคุณภาพ เนื่องจากมีส่วนของ Logic บางส่วนที่ซ้ำซ้อนกัน เมื่อต้องการแก้ไข Source Code ส่วนที่ซ้ำกันนี้ เราจำเป็นต้องตามไปแก้ทั้ง 2 ที่ ซึ่งถ้ามี 2 ที่ก็คงจะไม่ได้ยากเท่าไหร่ ปัญหาคือ เราจะรู้ได้อย่างไรว่ามีกี่ที่กันแน่ แล้วที่ที่ 2 นั้นอยู่ใน Module ไหน บรรทัดที่เท่าไหร่ ถ้า Source Code นั้นเราเป็นคนเขียนโปรแกรมขึ้นมาเองก็คงไม่ยากเท่าไหร่ แต่ถ้าไม่ใช่เราเป็นคนเขียนล่ะ หรือ เราเขียนเองแต่เวลาอาจผ่านไปนานจนเราลืมไปหมดแล้วว่าเราเขียนโปรแกรมไว้อย่างไร

ดังนั้นจึงเป็นกฏที่เราต้องนึงถึงอยู่เสมอเวลาทำการเขียนโปรแกรมคือ DRY ย่อมาจาก Don’t Repeat Yourself ในทาง Software Engineering จะถือว่านี่เป็นหลักการที่สำคัญข้อนึงในการเขียนโปรแกรม “อย่าทำการเขียน Code ซ้ำของเดิม” ซึ่งจริงๆแล้วเราคงไม่นั่งเขียนโปรแกรมซ้ำของตัวเอง 2 รอบ แต่เรามักจะใช้การ Copy Source Code ไปวาง แล้วแก้ไข Logic นิดหน่อย

วิธีแก้ไขคือแยก ส่วนที่ซ้ำออกมาสร้างเป็น function แล้วให้ Code ทั้ง 2 ส่วนนั้นเรียกใช้งาน function ที่สร้างขึ้นมาใหม่นี้ แต่ต่างกันที่ parameter ที่อาจส่งเข้าไปไม่เหมือนกัน