Saladpuk.com
🏆 เนื้อหาหลัก
🏆 เนื้อหาหลัก
  • 💖สลัดผัก
  • 📰มีอะไรใหม่บ้าง
    • 2020
      • 2020-11
      • 2020-10
      • 2020-09
      • 2020-08
      • 2020-03
      • 2020-02
      • 2020-01
    • 2019
      • 2019-12
      • 2019-11
      • 2019-10
      • 2019-09
      • 2019-08
  • 🤔อ่านเรื่องไรดี ?
  • มือใหม่หัดเขียนโค้ด
    • 👶เขียนโค้ดด้วยภาษา C#
      • เกิดมาไม่เคยเขียนโค้ดมาก่อนเบย
      • 👶พื้นฐาน
        • 1.โปรแกรมที่ต้องลง
        • 2.โครงสร้างของโค้ด
        • 3.ชนิดของข้อมูล
        • 4.การสร้างตัวแปร
        • 5.คำสั่งพื้นฐาน
        • 6.การแปลงข้อมูล
        • 7.การเปรียบเทียบค่า
        • 8.การตัดสินใจด้วย IF statements
        • 9.การตัดสินใจด้วย Switch statements
        • 10.การทำงานซ้ำๆด้วย While
        • 11.การทำงานซ้ำๆด้วย Do While
        • 12.การทำงานซ้ำๆด้วย For
        • 13.การแก้โจทย์จากรูป
        • 14.มารู้จักกับ Array กัน
      • 🧑ระดับกลาง
        • 15.Value type vs Reference type
        • 16.ลดงานซ้ำๆด้วย Method
        • 17.มารู้จักกับ Class & Field กัน
        • 18.มารู้จักกับ Constructor กันบ้าง
        • 19.มาเขียน Method ใน Class กัน
        • 20.มารู้จักกับ Property กัน
        • 21.ลองใช้คลาสแบบจริงจังบ้าง
        • 22.การสืบทอด Inheritance
        • 23.Polymorphism
        • 24.Abstract Class
        • 25.Interface
        • 26.Namespace
        • 27.Enum
        • 28.Exception handler
        • 29.ลงลึกกับ string
        • 30.StringBuilder เพื่อนคู่ string
      • 👨⏳ระดับสูง
        • Generic
        • Delegates
        • Action & Func
        • Lambda expression
        • LINQ
        • พระคัมภีร์การใช้คำสั่ง LINQ
      • 💡Tips
        • 💡C# version 8.0
        • 💡Boxing & Unboxing
    • 👶Algorithm
      • 👾Algorithm Big-O
      • 👽Algorithm P & NP
    • 👦OOP
      • 💖Abstraction
      • 💖Encapsulation
      • 🏆Abstraction & Encapsulation
      • 💖Inheritance
      • 💖Polymorphism
      • 🏆Inheritance & Polymorphism
      • 📝ลองเขียน OOP ดูดิ๊
      • 👑OOP + Power of Design
      • 🥰เทคนิคในการออกแบบ
    • 👶บทสรุปฐานข้อมูล
      • เก็บรูปในฐานข้อมูล
      • Database indexing
      • การลบข้อมูล
    • 👦Communication Patterns
    • 👦Design Patterns
      • 🤰Creational Patterns
        • 🏭Factory Method
        • 🏭Abstract Factory
        • ☝️ Singleton Pattern
        • 🏗️ Builder Pattern
        • 🎎Prototype Pattern
      • 🧱Structural Patterns
        • 🔌Adapter Pattern
        • 📪Proxy Pattern
  • Puzzle
    • 🧠Challenges
      • 🐴Google ม้า 25 ตัว
      • 🌉Amazon เสา 2 ต้น
      • 🥇ทองเก๊
      • 💊ยาต้านโควิด
      • 🎩CP หมวก 5 ใบ
      • 🧓Einstein's Riddle 01
  • พื้นฐานที่ควรต้องรู้
    • 🐳Docker
      • 📦Docker Containers
      • 🃏Docker Exercise 01
      • 🛠️ Docker Tools
      • 🗃️ Docker Registry
      • 🖼️ Container Image
      • 📢Docker Push
      • 🔄WSL
    • 👶Clean Code
      • 🧓Uncle Bob - Clean Code
      • 🧓Uncle Bob - Comments
      • 🧓Uncle Bob - Naming
      • 🧓Uncle Bob - Mindset
      • 🧓Uncle Bob - TDD
    • 👶Code Smells
    • 👶สิ่งที่คนเขียนโค้ดมักเข้าใจผิด
    • 👶AI พื้นฐาน
    • 👶Git พื้นฐาน
      • Git branching strategy
    • 👶Cloud พื้นฐาน
    • 👶UML พื้นฐาน
      • Activity Diagram
      • Class Diagram
      • Sequence Diagram
      • Use case Diagram
      • บทสรุปการใช้ UML
    • 👶Data Scientist
      • การเลือก Algorithms ให้ AI (1/5)
      • การเตรียมข้อมูลให้ AI (2/5)
      • หลักการตั้งคำถามให้ AI (3/5)
      • แฉความลับของ AI Model (4/5)
      • หัดเขียน AI จาก AI ของคนอื่น (5/5)
    • 👶DevOps พื้นฐาน
    • 👶Docker ขั้นพื้นฐาน
      • Image and Container
      • แชร์ Docker Image ที่สร้างไว้
    • 👶Microservices พื้นฐาน
      • Microservices ที่ดีมีลักษณะยังไง
      • Microservices Tips
      • จาก Monolith สู่ Microservices
    • 👶ความรู้พื้นฐานในการทำเว็บ
    • 👦Bottlenecks of Software
      • หัวใจที่สำคัญที่สุดของฐานข้อมูล
    • 👦Agile Methodology
      • Agile in a Nutshell
      • Software Development Life Cycle
      • Code Review
    • 👦Security พื้นฐาน
      • การเก็บรหัสผ่านที่ถูกต้อง
      • Security in actions
        • Hash function
      • Security Principles
      • 😎The Matrix 1
      • 😎The Matrix 2
      • HTTPS in a nutshell
    • 👦SOLID Design Principles
      • มารู้จักกับ SOLID กันดีกว่า
      • Single-Responsibility Principle
      • Open/Closed Principle
      • Liskov Substitution Principle
      • Interface Segregation Principle
      • Dependency-Inversion Principle
  • Cloud Computing
    • 👶Microsoft Azure 101
      • สมัคร Microsoft Azure
      • รู้จักกับ Resource Groups
      • สร้างเว็บตัวแรกกัน
      • สร้าง Virtual Machine กัน
      • ประเภทของคลาว์เซอร์วิส
      • มาสร้าง Logic App กัน
      • มาสร้าง Function App กัน
      • คลาว์คิดเงินยังไง ?
      • Cloud Native
      • Guideline for Cloud scaling
      • Auto Scaling
    • 👶Azure App Services
    • 👶App Service Plan
    • 👶Azure Storage
      • Blob storage
        • ลองสร้างที่เก็บไฟล์กันเลย
        • เข้าใจ Blob storage ให้มากขึ้น
        • ลองเขียนโค้ดอัพโหลดไฟล์กันบ้าง
        • สร้างเว็บจากที่ฝากไฟล์บนคลาว์
    • 👶Azure Bot Service
      • Bot เข้าใจเราได้ยังไงกันนะ
    • 👶Azure Cognitive Services
      • การสร้าง Cognitive Services
      • การ Login ด้วยใบหน้า
      • อ่านลายมือจากรูปเป็นตัวอักษร (OCR)
      • เขียน AI แยกของต่างๆทำยังไง?
      • เขียนแอพ ทายอายุ บอกเพศ ง่ายจิ๊ดเดียว
      • เขียนแอพให้ AI อธิบายรูปเป็นภาษาคน
    • 👶Machine Learning Studio
      • มาสร้าง AI ของแท้ตัวแรกของเรากัน
      • สร้าง AI ตัดสินใจอนุมัติบัตรเครดิต 💳
      • ลองเรียกใช้ AI ของเรากัน
    • 👶Azure Service Fabric
      • สร้าง Service Fabric กัน
    • 👶Blockchain
      • Blockchain ทำงานยังไง ?
      • Consensus Algorithm คืออะไร ?
      • สร้าง Blockchain ใช้เองกัน !
      • หัดเขียน Smart Contract กัน
    • 👶Power BI
    • 👶Azure Web App
      • เซิฟเวอร์บนคลาว์ ราคา? ต่าง?
    • 👶Azure DevOps
      • เล่น Azure DevOps กัน
      • เล่นกับ Repository
      • ลองทำ Continuous Integration (CI)
      • ลองทำ Continuous Delivery (CD)
      • เล่น Kanban Board
    • 🤠Cloud Playground
      • การป้องกันความลับหลุดตอนที่ 1
      • การป้องกันความลับหลุดตอนที่ 2
      • การป้องกันความลับหลุดตอนที่ 3
      • การป้องกันความลับหลุดตอนจบ
  • Software Testing
    • 👦Test-First Design
    • 👦Test-Driven Development
      • 1.มารู้จักกับ TDD กันดีกว่า
      • 2.Test cases เขาเขียนกันยังไงนะ
      • 3.เครื่องมือในการทดสอบ
      • 4.การใช้ Theory และ InlineData
      • 5.โค้ดที่ทดสอบได้
      • 6.Mantra of TDD
      • 7.Functional & None-Functional testing
      • 8.Manual vs Automation testing
      • 9.Automation Frameworks in .NET
      • 10.Mock Framework
      • 11.มาเรียนการใช้ Moq กันเถอะ
      • 12.สรุป
  • Web
    • 👦Web API
      • 1.Web API คืออะไร
      • 2.ติดตั้ง .NET Core SDK
      • 3.สร้าง Web API ตัวแรกกัน
      • 4.Verbs
      • 5.Swagger เพื่อคู่ API
      • 6.การใช้ Model
      • 7.เรียก Web API ผ่าน Postman
      • 8.มาจัดกลุ่ม API กัน (1/2)
      • 9.มาจัดกลุ่ม API กัน (2/2)
  • Software Design
    • 🤴Design Patterns
      • 🦈Creational patterns
        • Abstract Factory
        • Builder
        • Factory Method
        • Prototype
        • Singleton
      • 🦈Structural patterns
        • Adapter
        • Bridge
        • Decorator
        • Facade
        • Proxy
      • 🦈Behavioral patterns
        • Chain of Responsibility
        • Command
        • Iterator
        • Mediator
        • Memento
        • Observer
        • State
        • Strategy
        • Template Method
        • Visitor
Powered by GitBook
On this page
  • ❓ โค้ดส่งกลิ่นเน่าแล้วไง ?
  • 🤢 อาการของกลิ่นเน่า
  • 👃 Rigidity (ดื้อ)
  • 👃 Fragility (เปราะบาง)
  • 👃 Immobility (ย้ายที่ไม่ได้)
  • 👃 Viscosity (หนืด)
  • 👃 Needless Complexity (ซับซ้อนโดยไม่จำเป็น)
  • 👃 Needless Repetition (ใช้โค้ดซ้ำโดยไม่จำเป็น)
  • 👃 Opacity (เข้าใจยาก)
  • 🤔 ทำไมโค้ดถึงเน่า ?
  • 🎯 บทสรุป
  • 👨‍🚀 คอร์สที่จะช่วยให้โค้ดไม่เน่า

Was this helpful?

Export as PDF
  1. พื้นฐานที่ควรต้องรู้

Code Smells

โค้ดคุณส่งกลิ่นเน่าออกมาหรือเปล่า ?

เวลาที่เราทำงานกับโค้ดอยู่เคยรู้สึกแปลกๆกับโค้ดกันไหม เช่น ทำไมต้องเขียนแบบนี้ ทำไมใช้ยากจัง มันควรเป็นแบบนี้จริงๆเหรอ อะไรทำนองนี้ นั่นแหละคือสัญญาณแบบนึงที่บอกว่าโค้ดพวกนั้นกำลังมีปัญหา ซึ่งเขาเรียกว่ามันกำลังส่งกลิ่นเหม็นออกมา ดังนั้นหน้าที่ของ developer ที่ดีคือไล่ตามกลิ่นพวกนั้นไปแล้วจัดการอย่าให้โค้ดเน่าซะ ( ไม่ต้องเอาจมูกไปชิดจอแล้วไล่ดมโค้ดชาวบ้านไปทั่วนะครับ 🤣 )

Code smells คือหลักการที่เอาไว้ตรวจว่า โค้ดที่เราออกแบบไว้มันไปผิดหลักการออกแบบหรือเปล่า ซึ่งถ้าผิดมันหมายความว่าโครงสร้างพวกนั้นจะมีปัญหาในอนาคต และมีอีกชื่อนึงคือ Design Smells

❓ โค้ดส่งกลิ่นเน่าแล้วไง ?

คุณอยากทำงานกับโปรเจคแบบนี้ไหม แก้โค้ด 1 จุด bug ผุดกระจาย หรือ เพิ่ม 1 feature แต่ต้องไปแก้ 10 feature ที่ไม่เกี่ยวข้องด้วยไม่งั้นเพิ่ม feature ใหม่ไม่ได้ และอื่นๆอีกมากมาย ซึ่งถ้าไม่โรคจิตพอก็น่าจะตอบว่า "ไม่" แล้วถามต่อว่า แล้วจะมีใครอยากมาทำงานโปรเจคแบบนี้ไหม? คนที่อยู่ในโปรเจคแบบนี้เขาอยากรีบหนีไปทำโปรเจคอื่นไหม? นี่ยังไม่นับรวมเรื่อง deadline ของโปรเจคนี้ที่กำลังบีบเข้ามาด้วยนะ ... แค่นี้ก็น่าจะเห็นภาพแล้วใช่ไหมว่า โค้ดเน่ามันส่งผลเสียยังไง . . . หรือก็เป็นอยู่จนชินกันแล้ว ? 😱

🤢 อาการของกลิ่นเน่า

👃 Rigidity (ดื้อ)

คืออาการของโค้ดที่แก้ไขเพิ่มเติมยาก แม้ว่าจะเป็นแค่เรื่องง่ายๆก็ตาม เช่น แก้ 1 จุด แต่มันไปกระทบกับโค้ดอื่นๆที่เกี่ยวข้องกับมัน ทำให้เราต้องไปตามแก้เพื่อให้มันทำกับแบบใหม่ได้ แย่กว่านั้นอีกแก้ A กระทบ B, แก้ B กระทบ C, แก้ C ดันย้อนมากระทบ A เป็นงูกินหาง

แก้ 1 กระทบ 10 เคยไหมคิดว่าจะแก้โค้ดแค่ 1-2 วันวัน แต่พอทำไปทำมาบางทีกินเวลาเป็น 1-2 อาทิตย์เลย ทำให้เราไม่สามรถประเมินว่างานจะเสร็จเมื่อไหร่ได้เลย 😧

👃 Fragility (เปราะบาง)

คืออาการของโค้ดที่ แก้ 1 จุด bug ผุดเป็นดอกเห็ด เลวร้ายกว่านั้นอีก bug ที่ผุดขึ้นมาในบางทีไม่เกี่ยวข้องกับเรื่องนั้นเลย เช่น แก้โปรแกรมลงเวลา แล้ว bug ไปเกิดตอนคำนวณเงินเดือน ยิ่งแก้ก็ยิ่งผลิด bug ออกมาไม่จบไม่สิ้น

แก้ 1 จุด bug ผุดเป็นดอกเห็ด เคยไหม bug มันเยอะแก้ยังไงก็ไม่หมด จนคิดว่าเขียนส่วนนั้นใหม่ตั้งแต่ต้นอาจจะเร็วกว่า ปัญหานี้ developer ทุกคนรู้จักดี และบางครั้งรู้ด้วยว่ามันเป็นไฟล์นี้ แต่ไม่มีคนอยากไปแก้มันเพราะกลัวฟาร์มเห็ดจะผลิบาน

👃 Immobility (ย้ายที่ไม่ได้)

คืออาการของโค้ดที่เรารู้สึกว่ามันไม่ควรอยู่ตรงนี้นะ แต่ก็ย้ายมันออกจากตรงนี้ไม่ได้เพราะมันถูกใช้งานอยู่ และถ้าจะย้ายมันไปที่ๆของมันก็อาจจะเสียเวลามากจนไม่คุ้ม (พบเจอได้บ่อยกับพวก helper class กับ database connector หรือไม่ก็โค้ดที่คนอื่นเขียนไว้ไม่อยากไปยุ่งกับมัน)

👃 Viscosity (หนืด)

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

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

👃 Needless Complexity (ซับซ้อนโดยไม่จำเป็น)

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

ซับซ้อนโดยไม่จำเป็น ตัวอย่างที่เจอได้ง่ายสุดๆคือ จะแสดงเลขทศนิยมสูงสุดเพียงแค่ 2 ตำแหน่ง เช่น 3.1415 จะต้องแสดงเป็น 3.14 แต่ developer ไปเขียนสูตรคำนวณเพื่อตัด string หรือไม่ก็ x 100 เข้า แล้วหาร 100 ออกบลาๆ ซึ่งทำไมไม่ใช่ Math.Round() แฟร๊ พูดแล้วขึ้น 😡

👃 Needless Repetition (ใช้โค้ดซ้ำโดยไม่จำเป็น)

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

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

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

👃 Opacity (เข้าใจยาก)

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

🤔 ทำไมโค้ดถึงเน่า ?

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

พูดสั้นๆ กลับไปเก็บ exp มาให้เยอะๆซะ (รวมถึงผมด้วย) เพราะการเขียนซอฟต์แวร์ต้องเรียนรู้ตลอดไปไม่สามารถหยุดเรียนได้ เทคโนโลยีในตอนนี้เปลี่ยนวันต่อวันเลยทีเดียว 🤧

🎯 บทสรุป

โค้ดเน่าทำให้การพัฒนาซอฟต์แวร์กลายเป็นนรก เพราะ โปรเจคประเมินเวลาและค่าใช้จ่ายไม่ได้ ไม่มีคนอยากทำโปรเจคนั้น ดังนั้นจงอย่าทำให้มันเน่า

แล้วจะทำยังไงมันถึงจะไม่เน่า ? ... ออกไปเก็บประสบการณ์ซะ อ่านโค้ดจาก GitHub คนที่เก่งๆ ร่วม Contribute source code กับ GitHub ระดับโลกซักตัว เราจะได้รับคำแนะนำมาเต็มเลย และที่สำคัญที่สุดคือไปศึกษาหลักการออกแบบที่ดีมาซะ

👨‍🚀 คอร์สที่จะช่วยให้โค้ดไม่เน่า

PreviousUncle Bob - TDDNextสิ่งที่คนเขียนโค้ดมักเข้าใจผิด

Last updated 5 years ago

Was this helpful?

👶
👦SOLID Design Principles
👦Test-Driven Development
🤴Design Patterns