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
  • 👑 หัวใจหลักของ Interface Segregation Principle (ISP)
  • ❓ ทำไมต้องห้ามมี method ที่ไม่ได้ใช้ในโค้ด ?
  • 🥶 ตัวอย่างการเกิด Interface Pollution
  • 😒 ควรออกแบบยังไงดี
  • 😄 แยกการผูกกันโดยใช้ตัวแทน
  • 😄 แยกการผูกกันโดยการแยก Inheritance ตามความเหมาะสม
  • 🎯 บทสรุป

Was this helpful?

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

Interface Segregation Principle

PreviousLiskov Substitution PrincipleNextDependency-Inversion Principle

Last updated 5 years ago

Was this helpful?

👑 หัวใจหลักของ Interface Segregation Principle (ISP)

Clients should not be forced to depend on methods they do not use.

"โค้ดไม่ควรจะถูกบังคับให้มี method ที่ไม่ได้ใช้" ฟังแล้วก็เหมือนจะง่ายดีนะ ก็แค่อย่าเอา method ที่ไม่ได้ใช่ไปใส่ในโค้ดก็พอแล้วใช่ไหม? (ไม่เห็นต้องบอกเลยใครมันจะไปเขียน method ลงไปในโค้ดมั่วๆกันแฟร๊)

แต่เพื่อนๆเคยเจอไหมว่าในบางทีโค้ดเราถูกบังคับให้เติม method ที่ไม่ได้ใช้ลงไป เพราะ Interface หรือ Base Class กำหนดว่ามันต้องมียังไงล่ะ 😱 !! ซึ่งเหตุการณ์แบบนี้เราเรียกว่า Interface Pollution หรือ Fat Interface นั่นเอง แบ๊วเราจะจัดการยังไงกันดีล่าาาาา

Interface Pollution คือคำที่เรียกอาการของ Interface ที่โดนรวมกับ interface อื่นๆจนมันบวมฉ่ำ (fat) ลองคิดดูว่า Class ที่จะไป implement interface นั้นจะต้องเตรียมรับแรงกระแทกของ method ปริมาณมากยังไงดี และ ทุก method ที่หลั่งไหลเข้ามาคลาสนั้นจำเป็นต้องใช้จริงๆหรือเปล่า ?

❓ ทำไมต้องห้ามมี method ที่ไม่ได้ใช้ในโค้ด ?

ถ้าคลาสถูกบังคับจาก Interface ว่าจะต้องมี method ต่างๆ โดยที่ตัวมันเองไม่ได้ใช้ นั่นหมายความว่าคลาสพวกนั้นถูกผูกติด (coupling) กับ Interface ที่มี method ขยะปนมาด้วย และถ้า Interface พวกนั้นไปเพิ่ม method ขยะเข้าไปอีก นั่นก็หมายความว่า เราก็ต้องไปไล่ implement method ขยะด้วยทุกๆครั้งด้วยนะซิ และคลาสนั้นก็จะมีความเป็น Cohesion ลดลงไปด้วยนั่นเอง (Cohesion คือไรไปอ่านเอาบนแรกๆที่ side menu นู่นเลย) และที่แย่ที่สุดของปัญหานี้คือโค้ดเรามี Rigidity และ Viscosity สูงมาก

Code Smells Rigidity - โค้ดแก้ไขเพิ่มเติมยาก Viscosity - มีโอกาสที่แก้ไขปัญหาแบบผิดวิธี ออกนอกลู่นอกทาง * เรื่องของ Code Smells แบบเต็มๆไปอ่านเอาได้จาก side menu เด้อ

🥶 ตัวอย่างการเกิด Interface Pollution

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

public interface IElectronic
{
    void TurnOn();
    void TurnOff();
    bool IsTurnedOn();
}

public class Television : IElectronic { ... }
public class LightBulb : IElectronic { ... }

แล้วอยู่มาวันนึง เราก็อยากให้หลอดไฟและทีวีสามารถตั้งเวลาปิดได้เองอัตโนมัติ ดังนั้นเราก็เลยเพิ่มโค้ดเข้าไปอีกนิสนุง ตามรูปด้านล่าง

ดูผิวเผินก็เหมือนไม่มีอะไร แค่ต้องไปเพิ่ม method ให้กับ LightBulb กับ Television เข้าไปหน่อยให้มันสามารถตั้งเวลาปิดได้ จนกระทั่งได้อ่านข้อความบรรด้านล่าง

ลูกค้าอยากให้มีทีวีและหลอดไฟแบบโบราณซึ่งมันไม่สามารถตั้งเวลาปิดได้ เราจะออกแบบยังไง? ส่วนใหญ่ก็จะออกมาเป็นตามภาพด้านล่าง

เจ้าคลาสใหม่ 2 ตัวที่เพิ่มเข้ามา จะต้องถูกยัดเยียดให้ implement SetTurnOffSchedule() เข้าไปด้วย ทั้งๆที่มันไม่ได้ใช้

ลองคิดดู ถ้าในอนาคตมีหลอดไฟหรือทีวี แบบใหม่ๆเข้ามา เช่นสั่งงานด้วยเสียงได้ สั่งงานผ่าน bluetooth ได้ หรืออะไรก็ตามแต่เข้ามาเรื่อยๆ จะเกิดอะไรขึ้นกับคลาสที่ implement interface พวกนี้? นี่แหละปัญหาของ Interface Pollution 💀

😒 ควรออกแบบยังไงดี

😄 แยกการผูกกันโดยใช้ตัวแทน

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

public class ElectronicScheduler : ISwitchScheduler
{
    public IElectronic Electronic { get; set; }

    public ElectronicScheduler(IElectronic electronic)
    {
        Electronic = electronic;
    }

    public void SetTurnOffSchedule(int seconds)
    {
        var timer = new Timer(seconds * 1000);
        timer.Elapsed += (sndr, se) =>
        {
            timer.Stop();
            Electronic.TurnOff();
        };
        timer.Start();
    }
}

👍 ข้อดีในการออกแบบ เมื่อยกหน้าที่การรับผิดชอบไปให้กับตัวแทนแล้ว ข้อดีที่ได้คือ ต่อให้ ISwitchScheduler มีการเปลี่ยนแปลงไปยังไงก็ตาม มันก็จะไม่มีผลกระทบกับตระกูล Electronic เลย กระทบแค่ ElectronicScheduler ตัวเดียวเท่านั้น และก็สมควรแล้วเพราะเป็นหน้าที่ดูแลของมัน

👎 ข้อเสียในการออกแบบ ทุกครั้งที่สร้าง object ของ Electronic ที่ตั้งเวลาได้ เราจะต้องสร้าง object ของ ElectronicScheduler ตามมาด้วยเสมอ

😄 แยกการผูกกันโดยการแยก Inheritance ตามความเหมาะสม

แทนที่เราจะเหมารวม Electronic ทุกประเภทจะต้องตั้งเวลาได้ เราก็แค่แยกการทำ Inheritance ตามความเหมาะสมของแต่ละคลาสก็เพียงพอแล้ว และแบบนี้ค่อนข้างที่จะเบาสบายกว่าด้วย

🎯 บทสรุป

การละเมิดกฎของ ISP ทำให้โค้ดเกิด Coupling, Rigidity และ Viscosity ขึ้นสูงมาก เมื่อ fat interface มีการแก้ไข เราจะต้องไล่ตามเช็คทุกๆคลาสที่ใช้ interface นั้น วิธีการแก้ไขที่ง่ายที่สุดคือการแตก interface ออกเป็นเรื่องๆ แล้วให้เฉพาะคลาสที่ต้องใช้จริงๆไป implement interface เท่าที่ต้องใช้เท่านั้น

👦