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
  • Adapter
  • 🎯 เป้าหมายของ pattern นี้
  • ✌ หลักการแบบสั้นๆ
  • 😢 ปัญหา
  • 😄 วิธีแก้ไข
  • 📌 โครงสร้างของ pattern นี้
  • 🛠 ตัวอย่างการนำไปใช้งาน
  • 👍 ข้อดี
  • 👎 ข้อเสีย
  • ‍‍📝 Code ตัวอย่าง

Was this helpful?

Export as PDF
  1. Software Design
  2. Design Patterns
  3. Structural patterns

Adapter

PreviousStructural patternsNextBridge

Last updated 5 years ago

Was this helpful?

Adapter

Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

🎯 เป้าหมายของ pattern นี้

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

✌ หลักการแบบสั้นๆ

  1. สร้าง interface ที่เราอยากจะทำงานด้วยขึ้นมา แล้วทำงานกับ interface นั้นแทน

  2. นำ interface ที่เราสร้างขึ้นมาไปทำงานร่วมกัน class ที่ต้องการทำงานด้วย

😢 ปัญหา

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

จนมาถึงวันหนึ่ง เง็กเซียนได้ข่าวมาว่า มีบริษัทหนึ่งขาย library สำหรับวิเคราะห์หุ้นขั้นเทพ ที่ให้ผลแม่นดุจตาเห็น!! ดังนั้นเง็กเซียนเลยตัดสินใจซื้อ library ที่ว่านั้นมา

แต่เง็กเซียนแทบหงายเงิบ เพราะ library ที่ซื้อมามันดันทำงานกับ JSON format ได้เท่านั้น!!

จากรูปเลยข้อมูลหุ้นวิ่งเข้าแอพของเง็กเซียนทำงานได้ตามปรกติ แต่มันเอาเข้าไปทำงานกับ library ที่ซื้อมาไม่ได้

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

และหลังจากไตร่ตรองอยู่นั่นเอง เง็กเซียนก็ตระหนักได้ว่า โค้ดนั่นมันเป็นของบริษัทอื่นนิหว่า มันแก้เองไม่ได้โว้ยยยย!! (นึกถึงหน้าจตุรเทพในเรื่องคุโรมาตี้ขึ้นมาเลย)

แล้วเง็กเซียนจะแก้ปัญหานี้อย่างไรดี . . .

😄 วิธีแก้ไข

เง็กเซียนก็โทรไปเพื่อซื้อบริษัทนั้นมา แล้วสั่งให้มันเขียนรองรับ XML จบข่าวววว (ฮา)

วิธีการแก้ไขปัญหาก็แสนจะง่าย ให้จินตนาการง่ายๆว่า สาย power โน๊ตบุ๊คเรามันมี 3 ขาใช่ปะ แต่เต้าเสียบไฟแบบทั่วๆไปมันจะมีรูให้เสียบแค่ 2 รู แล้วเราจะทำยังไงให้มันเสียบได้?? ... เราก็แค่ไปซื้อตัวแปลงจาก 3 ขาเป็น 2 ขามาใช้ไงละ!! (เคยมีครั้งนึงผมต้องหักสายกราวทิ้ง เพื่อให้มันมี 2 ขา จริงจังนะนิ -_-'')

ก่อนที่จะเมากาวไปมากกว่านี้ สิ่งที่เง็กเซียนต้องทำก็คือ สร้างสิ่งที่เรียกว่า Adapter ขึ้นมา

ซึ่งสิ่งที่เรียกว่า Adapter มันจะมีหน้าที่ห่อหุ้ม object ที่เราไม่สามารถทำงานร่วมกับมันเอาไว้ แล้วเปลี่ยนมันให้กลายเป็นของที่เราสามารถทำงานร่วมกับมันได้ รวมถึงจัดการความซับซ้อนของ object นั้นทั้งหมดอีกด้วย (ในตัวอย่าง adapter ก็คือตัวแปลงจาก 3 ขาเป็น 2 ขา)

และในบางครั้ง เราอาจจะต้องทำ Adapter ที่เป็น 2 ทาง (two-way adapter) คือ แปลงให้ฝั่ง A ใช้ฝั่ง B ได้ และยังต้อง แปลงให้ฝั่ง B ก็ใช้ฝั่ง A ได้ ด้วยช่วยกัน

จากภาพ เง็กเซียนก็จะสร้าง Adapter ขึ้นมาตัวนึงนั่นคือ XMLToJSONAdapter เอาไว้แปลงข้อมูล XML ไปเป็น JSON เพื่อส่งข้อมูลไปให้กับ library ที่ซื้อมานั่นเอง

📌 โครงสร้างของ pattern นี้

อธิบาย

  1. Client - คือคลาสที่ทำงานร่วมกับ interface ที่เป็นต้นแบบของ Adapter

  2. Client Interface - เป็นมาตรฐานในการสร้าง Adapter เพื่อให้ Client สามารถทำงานร่วมกับ class ที่ได้ตามที่ client คาดหวังไว้

  3. Service - class ที่แท้จริงที่ client ต้องทำงานร่วมด้วย ซึ่งปรกติ client จะไม่สามารถทำงานร่วมกับมันตรงๆได้

  4. Adapter - ตัวที่ทำหน้าที่จัดการให้ client ทำงานร่วมกับ class ที่แท้จริงที่ต้องทำงานร่วมกัน

  5. Client ทำงานร่วมกับ interface เท่านั้น ไม่ได้ทำงานร่วมกับ class ที่แท้จริง ทำให้เราสามารถเขียน Adapter แบบอื่นๆให้ client ทำงานรวมได้โดยที่ไม่ต้องเปลี่ยนโค้ดใดๆเราเลย

🛠 ตัวอย่างการนำไปใช้งาน

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

ดังนั้นเราก็จะสร้าง Adapter ขึ้น เพื่อใช้เป็นตัวแทนคุยกับ Youtube API อีกที (ดูใน Code ตัวอย่างเลย)

👍 ข้อดี

  • สามารถเปลี่ยน Adapter เมื่อไหร่ก็ได้ นั่นหมายความว่าเราสามารถเปลี่ยน library ของ 3rd party เป็นตัวอื่นได้เรื่อยๆ โดยไม่ต้องกลับไปแก้ไขโค้ดเก่าของเราเลย

  • ถูกหลัก Single Responsibility Principle

  • ถูกหลัก Open/Closed Principle

👎 ข้อเสีย

  • เพิ่มความซับซ้อนให้กับโค้ด เพราะต้องไปสร้าง class และ interface มากมาย

‍‍📝 Code ตัวอย่าง

// Youtube API & Models
public class YoutubeProfile
{
    public string Username { get; set; }
    public string DisplayName { get; set; }
    public DateTime BirthDate { get; set; }
}
public class YoutubeAPI
{
    public YoutubeProfile GetProfile()
    {
        return new YoutubeProfile
        {
            Username = "saladpuk",
            DisplayName = "Mr.SaladPuk",
            BirthDate = new DateTime(2000, 1, 1),
        };
    }
}

// Adapter & Models
public class AccountInfo
{
    public string Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
public interface IAccountAdapter
{
    AccountInfo GetAccountInfo();
}
public class YoutubeAdapter : IAccountAdapter
{
    private YoutubeAPI adaptee = new YoutubeAPI();

    public AccountInfo GetAccountInfo()
    {
        var profile = adaptee.GetProfile();
        var age = new DateTime() + (DateTime.Now - profile.BirthDate);
        return new AccountInfo
        {
            Id = profile.Username,
            Name = profile.DisplayName,
            Age = age.Year,
        };
    }
}

// Client
class Program
{
    static void Main(string[] args)
    {
        var adapter = new YoutubeAdapter();
        var acc = adapter.GetAccountInfo();
        Console.WriteLine($"Id: {acc.Id}, Name: {acc.Name}, Age: {acc.Age}");
    }
}

Output

Id: saladpuk, Name: Mr.SaladPuk, Age: 20

🤴
🦈
img
img
img
img