อะไรคือความแตกต่างระหว่างคลัปต่อหลวมและคลัปคับในกระบวนทัศน์เชิงวัตถุ


272

มีใครอธิบายความแตกต่างที่แน่นอนระหว่างคลัปข้อต่อหลวมและคลัปคับในกระบวนทัศน์เชิงวัตถุได้หรือไม่?


คำตอบ:


338

คับคัปปลิ้งคือเมื่อกลุ่มของคลาสนั้นพึ่งพากันมาก

สถานการณ์นี้เกิดขึ้นเมื่อชั้นเรียนมีความรับผิดชอบมากเกินไปหรือเมื่อมีข้อกังวลอย่างหนึ่งเกิดขึ้นในหลายชั้นเรียนมากกว่าที่จะมีชั้นเรียนของตัวเอง

การแต่งงานกันแบบหลวม ๆ นั้นทำได้โดยการออกแบบที่ส่งเสริมความรับผิดชอบเดี่ยวและการแยกความกังวล

คลาสแบบคู่ที่หลวมสามารถใช้และทดสอบได้อย่างอิสระจากคลาสอื่น ๆ (คอนกรีต)

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

ตัวอย่างการมีเพศสัมพันธ์แน่น:

class CustomerRepository
{
    private readonly Database database;

    public CustomerRepository(Database database)
    {
        this.database = database;
    }

    public void Add(string CustomerName)
    {
        database.AddRow("Customer", CustomerName);
    }
}

class Database
{
    public void AddRow(string Table, string Value)
    {
    }
}

ตัวอย่างการมีเพศสัมพันธ์แบบหลวม:

class CustomerRepository
{
    private readonly IDatabase database;

    public CustomerRepository(IDatabase database)
    {
        this.database = database;
    }

    public void Add(string CustomerName)
    {
        database.AddRow("Customer", CustomerName);
    }
}

interface IDatabase
{
    void AddRow(string Table, string Value);
}

class Database implements IDatabase
{
    public void AddRow(string Table, string Value)
    {
    }
}

อีกตัวอย่างหนึ่งที่นี่


จนถึงสิ่งที่คุณพูดมีเหตุผลอย่างสมบูรณ์แบบคุณสามารถอธิบายกลไกการแต่งงานที่สัมพันธ์กับรูปแบบการสังเกตการณ์ได้อย่างไร
Jim

1
รูปแบบการสังเกตการณ์อธิบายไว้ที่นี่: en.wikipedia.org/wiki/Observer_pattern เนื่องจากคลาส Subject สามารถรักษารายการของคลาสที่สืบทอดมาจาก 'Observer' โดยไม่ทราบชนิดที่เป็นรูปธรรมของคลาสเหล่านั้นจึงเป็นตัวอย่างของการมีเพศสัมพันธ์แบบหลวม หัวเรื่องไม่ได้ขึ้นอยู่กับผู้สังเกตการณ์หรือข้อกังวลภายใน ผู้สังเกตการณ์ไม่ได้ขึ้นอยู่กับหัวเรื่องหรือข้อกังวลใด ๆ
Jonathan

4
Java interfaces เป็นเครื่องมือที่สามารถช่วยได้ อย่างไรก็ตามพวกเขาไม่จำเป็นต้องใช้ แนวคิดของโปรแกรมไปยังส่วนต่อประสานที่ไม่ใช้งานหมายถึงโปรแกรมไปยังวิธีการ / คุณลักษณะสาธารณะ (หรือรายการที่ผู้โทรภายนอกใช้เมื่อภาษาไม่รองรับการปรับเปลี่ยนการเข้าถึงเช่น C) อินเทอร์เฟซควรจะเคารพสัญญาโดยนัยนี้โดยไม่เปลี่ยนแปลง ในภาษาที่ไม่มีตัวดัดแปลงการเข้าถึง (เช่น C) หมายถึงเฉพาะการใช้อินเทอร์เฟซ / ฟังก์ชั่นที่เผยแพร่และไม่ตีสิ่งที่มีไว้เพื่อใช้ภายในเนื่องจากอาจมีการเปลี่ยนแปลงตามความจำเป็นเพื่อรองรับฟังก์ชั่นที่เผยแพร่
Bill Rosmus

3
@ Jonathanconway ขอบคุณมากครับ แต่ทั้งสองโค้ดทำสิ่งเดียวกัน: แล้วอะไรคือความแตกต่างระหว่างพวกเขา? อะไรคือข้อดีของการมีเพศสัมพันธ์อย่างหลวม ๆ ?
BKSpurgeon

1
ฉันเคยเห็น (โดยพื้นฐาน) ตัวอย่างนี้มาก่อน ในความคิดของฉันไม่ว่าจะมีความสำคัญหากมีฐานข้อมูลหลายประเภทที่จะใช้ หากคุณวางแผนที่จะมีเพียงหนึ่งเดียวมันก็ไม่ดีที่จะใช้การใช้งานโดยตรงแล้วในภายหลังถ้าคุณจะต้องฉีดประเภทต่าง ๆ จากนั้น refactor ใช้ฐานข้อมูลเดียวที่จะใช้อินเตอร์เฟซ? แทนที่จะเพิ่มรหัสจานของหม้อไอน้ำซึ่งไม่น่าจะใช่ไหม?
Carlos Bribiescas

177

คำอธิบายโดยไม่มีรหัสใด ๆ

ตัวอย่างสรุป:

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

หมวกคือ "คู่ที่หลวม" กับร่างกาย  ซึ่งหมายความว่าคุณสามารถถอดออกได้อย่างง่ายดายโดยไม่ต้องทำการเปลี่ยนแปลงใด ๆ กับบุคคล / ร่างกาย  การแสดงรูปภาพ

คลัปแน่น (ตัวอย่างโดยละเอียด)

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

  • ประเด็นสำคัญ # 1 : กล่าวอีกนัยหนึ่งถ้าคุณต้องการเปลี่ยนสกินคุณจะต้องเปลี่ยนการออกแบบร่างกายของคุณด้วยเช่นกันเพราะทั้งสองเข้าด้วยกัน

พระเจ้าไม่ใช่โปรแกรมเมอร์ที่ดี

คลัปหลวม (ตัวอย่างโดยละเอียด)

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

  • นั่นคือจุดสำคัญ # 2 หากคุณเปลี่ยนเสื้อของคุณคุณจะไม่ถูกบังคับให้เปลี่ยนร่างกาย - เมื่อคุณสามารถทำเช่นนั้นคุณจะมีเพศสัมพันธ์แบบหลวม ๆ เมื่อคุณไม่สามารถทำเช่นนั้นได้คุณจะมีเพศสัมพันธ์อย่างแน่นหนา

นั่นคือแนวคิดพื้นฐานสั้น ๆ

ทำไมสิ่งสำคัญทั้งหมดนี้

เป็นสิ่งสำคัญเนื่องจากซอฟต์แวร์มีการเปลี่ยนแปลงตลอดเวลา โดยทั่วไปคุณต้องการให้สามารถแก้ไขรหัสของคุณได้อย่างง่ายดายโดยไม่ต้องเปลี่ยนรหัส ฉันรู้ว่ามันฟังดูเหมือน oxymoron แต่โปรดทนกับฉัน

ตัวอย่างการปฏิบัติของการแต่งงานกันในเมื่อการเข้ารหัส

  • ตัวอย่าง CSV / JSON / DB:ถ้ามีคนต้องการเอาท์พุทของพวกเขาในไฟล์ CSV แทนที่จะเป็น JSON ฯลฯ หรือถ้าคุณต้องการเปลี่ยนจาก MySQL เป็น PostGreSQL คุณควรจะสามารถเปลี่ยนแปลงสิ่งเหล่านี้ได้อย่างง่ายดายในรหัสของคุณโดยไม่ต้องเขียนซ้ำ ทั้งคลาสเป็นต้นกล่าวอีกนัยหนึ่งคุณไม่ต้องการคู่แอปพลิเคชันของคุณอย่างแน่นหนากับการใช้ฐานข้อมูลเฉพาะ (เช่น Mysql) หรือเอาต์พุตเฉพาะ (เช่นไฟล์ CSV) เพราะอย่างหลีกเลี่ยงไม่ได้ในซอฟต์แวร์การเปลี่ยนแปลงจะเกิดขึ้น เมื่อมาถึงมันจะง่ายขึ้นถ้าส่วนของรหัสของคุณเป็นคู่อย่างอิสระ

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

สรุป

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

ความแตกต่างและหลักการ SOLID

Re: @TimoHuovinen ความคิดเห็น - แนวคิดของข้อต่อหลวมไปจับมือกับแนวคิดของ polymorphism หากคุณเข้าใจความคล้ายคลึงพื้นฐานของชิ้นส่วนเสื้อ / รถยนต์คุณก็พร้อมที่จะเข้าใจถึงความหลากหลาย วิธีที่ดีที่สุด ณ จุดนี้คือการอ่านตัวอย่างโค้ดที่เพื่อนร่วมงานของฉันประเมินได้ในคำตอบอื่น ๆ ในชุดข้อความนี้ ถ้าฉันพูดอีกต่อไปคุณอาจได้รับข้อมูลมากเกินไป

รูปภาพแสดงที่มา


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

6
มีบางสิ่งที่จะต้องมีการจับคู่อย่างแน่นหนาและบางคู่กับสภาพแวดล้อมที่คับ การใช้ผิวหนังไม่ได้เป็นอุปมาที่เหมาะสมสำหรับการมีเพศสัมพันธ์อย่างแน่นหนา หากผิวถูกคิดว่าเป็นคู่อย่างแน่นหนากับร่างกายดังนั้นทุกส่วนอื่น ๆ ร่างกาย (โดยรวม) จะต้องมีชิ้นส่วน (บูรณาการอย่างแน่นหนา) เพื่อให้ทำงานได้อย่างถูกต้อง (อาจเป็นความคิดของธรรมชาติ - สถาปนิกที่ยอดเยี่ยม) หากชิ้นส่วนเหล่านั้นถูกออกแบบมาให้ถอดเปลี่ยนได้ (ง่ายเหมือนการเปลี่ยนหมวก) ดังนั้นความหมายของร่างกาย 'มนุษย์' จึงสูญเสียความหมายของมัน ความเห็นที่ 1/2
lupchiazoem

6
ไปตามตัวอย่างถ้าผิวหนังถูกทำให้เปลี่ยนได้หัวก็จะต้องเปลี่ยนใหม่ได้ หากสิ่งนั้นเกิดขึ้นผู้คนอาจไม่สามารถจดจำได้จากการพบปะสังสรรค์กับคนอื่น การมีเพศสัมพันธ์แบบคับแคบ / หลวมจะเป็นอย่างไร - รถยนต์และชิ้นส่วนคอมพิวเตอร์และชิ้นส่วน ฯลฯ ... หากมีปัญหากับเม้าส์ / แป้นพิมพ์ของคอมพิวเตอร์ก็สามารถเปลี่ยนเป็นส่วนอื่นได้แทนที่จะทำให้คอมพิวเตอร์ทั้งหมดไร้ประโยชน์ และทิ้ง ความคิดเห็นที่ 2/2
lupchiazoem

1
@BKSpurgeon คำอธิบายที่ยอดเยี่ยม !! และวิธีที่คุณใช้เป็นตัวอย่างในการอธิบายก็ดีเช่นกัน
Kiran Joshi

5
อธิบายอย่างสร้างสรรค์มาก ฉันคู่กับคำตอบนี้อย่างแน่นหนา
AliN11

72

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

คุณอาจพบว่าบทความนี้โดย Martin Fowler (PDF) มีประโยชน์


"การเปลี่ยนแปลงในระดับ A บังคับให้เกี่ยวข้องกับการเปลี่ยนแปลงในคลาส B บ่อยเพียงใด" ฉันต้องการตัวอย่างสั้น ๆ สำหรับประโยคข้างต้นหรือไม่?
Kumaresan Perumal

15

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

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

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

การมีเพศสัมพันธ์หมายถึงระดับของความรู้โดยตรงที่องค์ประกอบหนึ่งมีอีกส่วนหนึ่ง เราสามารถพูดได้เช่น: A และ B เพียง B เปลี่ยนพฤติกรรมของมันก็ต่อเมื่อ A เปลี่ยนพฤติกรรมของมัน ระบบคู่ที่หลวมสามารถแบ่งออกเป็นองค์ประกอบได้อย่างง่ายดาย


11

เมื่อวัตถุสองชิ้นเชื่อมโยงกันอย่างหลวม ๆ พวกมันสามารถโต้ตอบกันได้ แต่มีความรู้กันน้อยมาก

การออกแบบคู่ที่หลวมทำให้เราสามารถสร้างระบบ OO ที่ยืดหยุ่นซึ่งสามารถรับมือกับการเปลี่ยนแปลงได้

รูปแบบการออกแบบสังเกตการณ์เป็นตัวอย่างที่ดีสำหรับการเรียนคู่หลวมคุณสามารถดูได้บนไว้ในวิกิพีเดีย


6

สารสกัดจากการโพสต์บล็อกของฉันเมื่อมีเพศสัมพันธ์:

ลัปแน่นคืออะไร: -

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

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

ลองใช้รหัสตัวอย่างของตะกร้าสินค้าเพื่อทำความเข้าใจข้อต่อที่แน่นหนา:

namespace DNSLooseCoupling
{
    public class ShoppingCart
    {
        public float Price;
        public int Quantity;

        public float GetRowItemTotal()
        {
            return Price * Quantity;
        }
    }

    public class ShoppingCartContents
    {
        public ShoppingCart[] items;

        public float GetCartItemsTotal()
        {
            float cartTotal = 0;
            foreach (ShoppingCart item in items)
            {
                cartTotal += item.GetRowItemTotal();
            }
            return cartTotal;
        }
    }

    public class Order
    {
        private ShoppingCartContents cart;
        private float salesTax;

        public Order(ShoppingCartContents cart, float salesTax)
        {
            this.cart = cart;
            this.salesTax = salesTax;
        }

        public float OrderTotal()
        {
            return cart.GetCartItemsTotal() * (2.0f + salesTax);
        }
    }
}

มีปัญหากับตัวอย่างข้างต้น

คลัปแน่นสร้างปัญหาบางอย่าง

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


6

การมีเพศสัมพันธ์แบบหลวมหมายความว่าระดับการพึ่งพาระหว่างสององค์ประกอบนั้นต่ำมาก
ตัวอย่าง: GSM SIM

การมีเพศสัมพันธ์อย่างแน่นหนาหมายความว่าระดับการพึ่งพาระหว่างสององค์ประกอบนั้นสูงมาก
ตัวอย่าง: CDMA Mobile


5

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

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


5

การมีเพศสัมพันธ์อย่างแน่นหนาหมายถึงคลาสหนึ่งขึ้นอยู่กับคลาสอื่น
Loose Couplingหมายถึงคลาสหนึ่งขึ้นอยู่กับอินเตอร์เฟสมากกว่าคลาส

ในการแต่งงานกันอย่างแน่นหนามีการอ้างอิงรหัสตายยากในวิธีการ
ในการแต่งงานกันแบบหลวม ๆเราจะต้องผ่านการพึ่งพาจากภายนอกที่รันไทม์แทนการใช้รหัสตาย (ระบบคู่ที่หลวมใช้อินเทอร์เฟซเพื่อลดการพึ่งพากับคลาส)

ตัวอย่างเช่นเรามีระบบที่สามารถส่งเอาต์พุตในสองวิธีขึ้นไปเช่นเอาต์พุต JSON, เอาต์พุต CSV ฯลฯ

คับ

public interface OutputGenerator {
    public void generateOutput();
}

public class CSVOutputGenerator implements OutputGenerator {
    public void generateOutput() {
        System.out.println("CSV Output Generator");
    }
}

public class JSONOutputGenerator implements OutputGenerator {
    public void generateOutput() {
        System.out.println("JSON Output Generator");
    }
}

// In Other Code, we write Output Generator like...
public class Class1 {
    public void generateOutput() {
        // Here Output will be in CSV-Format, because of hard-coded code.
        // This method tightly coupled with CSVOutputGenerator class, if we want another Output, we must change this method.
        // Any method, that calls Class1's generateOutput will return CSVOutput, because Class1 is tight couple with CSVOutputGenerator.
        OutputGenerator outputGenerator = new CSVOutputGenerator();
        output.generateOutput();
    }
}

ในตัวอย่างข้างต้นถ้าเราต้องการที่จะเปลี่ยนผลลัพธ์ใน JSON แล้วเราจำเป็นต้องค้นหาและเปลี่ยนแปลงในรหัสทั้งหมดเพราะ Class1 เป็นคู่อย่างแน่นหนากับคลาส CSVOutputGenerator

คู่หลวม

public interface OutputGenerator {
    public void generateOutput();
}

public class CSVOutputGenerator implements OutputGenerator {
    public void generateOutput() {
        System.out.println("CSV Output Generator");
    }
}

public class JSONOutputGenerator implements OutputGenerator {
    public void generateOutput() {
        System.out.println("JSON Output Generator");
    }
}

// In Other Code, we write Output Generator like...
public class Class1 {
    public void generateOutput(OutputGenerator outputGenerator) {
        // if you want to write JSON, pass object of JSONOutputGenerator (Dependency will be passed externally to this method)
        // if you want to write CSV, pass object of CSVOutputGenerator (Dependency will be passed externally to this method)

        // Due to loose couple with class, we don't need to change code of Class1, because Class1 is loose coupled with CSVOutputGenerator or JSONOutputGenerator class
        // Any method, that calls Class1's generateOutput will desired output, because Class1 does not tight couple with CSVOutputGenerator or JSONOutputGenerator class
        OutputGenerator outputGenerator = outputGenerator;
        output.generateOutput();
    }
}

3

มีเครื่องมือบางอย่างที่ให้การฉีดผ่านไลบรารีของพวกเขาตัวอย่างเช่นใน. net เรามีห้องสมุดเก้าชั้น

หากคุณกำลังจะไปเพิ่มเติมใน java แล้วฤดูใบไม้ผลิให้ความสามารถนี้

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

พูดในรหัสของคุณว่าคุณกำลังเขียน

Myclass m = new Myclass();

ตอนนี้คำสั่งในวิธีการของคุณบอกว่าคุณจะขึ้นอยู่กับmyclassสิ่งนี้เรียกว่าคู่แน่น ตอนนี้คุณเตรียมการฉีดคอนสตรัคเตอร์หรือการฉีดคุณสมบัติและวัตถุอินสแตนซ์แล้วมันจะกลายเป็นคู่อย่างอิสระ


3

มีคำตอบที่ดีมากที่นี่โดยใช้การเปรียบเทียบ แต่เพื่อนในที่ทำงานให้ฉันตัวอย่างที่ฉันชอบมากกว่าทุกคนที่กล่าวถึงที่นี่ ... ตาและแว่นตา!

คลัปแน่น

การมีเพศสัมพันธ์แน่นจะเป็นตา ถ้าฉันต้องการที่จะแก้ไขวิสัยทัศน์ของฉันฉันมีราคาแพงมากที่จะได้รับการปลูกถ่ายตาและมีความเสี่ยงพอสมควร แต่ถ้านักออกแบบ (เป็นเผ่าพันธุ์มนุษย์) พบวิธีที่ดีกว่า เพิ่มฟีเจอร์ที่รวมเข้ากับร่างกายอย่างอิสระเพื่อให้สามารถเปลี่ยนได้อย่างง่ายดาย! (ใช่ .. แว่นตา)

คลัปหลวม

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

สรุป

ดังนั้นครั้งต่อไปที่มีคนถามคุณว่า "ใครจะสนใจว่ารหัสของฉันแน่นเป็นคู่หรือไม่" คำตอบคือทั้งหมดที่เกี่ยวกับความพยายามในการเปลี่ยนแปลงความพยายามในการรักษาและความเสี่ยงของการเปลี่ยนแปลง

ดังนั้นสิ่งนี้จะทำใน C #? การเชื่อมต่อและการพึ่งพาการฉีด!

แก้ไข

นี่เป็นตัวอย่างที่ดีของรูปแบบของมัณฑนากรเช่นกันซึ่งดวงตาเป็นคลาสที่เรากำลังตกแต่งตามข้อกำหนดของอินเทอร์เฟซ แต่ให้ฟังก์ชั่นที่แตกต่างกัน (เช่นแว่นกันแดดแว่นอ่านหนังสือแว่นขยายสำหรับอัญมณี ฯลฯ )


2

การมีเพศสัมพันธ์ที่หลวมและตอบสนองต่อการพึ่งพา hardcoded แบบเก่าและปัญหาที่เกี่ยวข้องเช่นการรวบรวมซ้ำบ่อยครั้งเมื่อมีการเปลี่ยนแปลงอะไรและนำโค้ดกลับมาใช้ใหม่ มันเน้นการใช้ตรรกะของผู้ปฏิบัติงานในส่วนประกอบและหลีกเลี่ยงการวางสายเฉพาะโซลูชันที่นั่น

Loose Coupling = IoC ดูสิ่งนี้สำหรับคำอธิบายที่ง่ายขึ้น


3
ฉันไม่คิดว่าการแต่งงานกันแบบหลวม ๆ จะเหมือนกับการกลับกันของการควบคุม การผกผันของการควบคุมเป็นเทคนิคที่มีประโยชน์มากสำหรับการลดการเชื่อมต่อของการออกแบบของคุณ แต่มีเทคนิคอื่น ๆ อีกมากมาย
Don Kirkby

2

Loose Coupling เป็นกระบวนการของการพึ่งพาชั้นเรียนที่คุณต้องการโดยทางอ้อมโดยไม่ต้องให้ข้อมูลทั้งหมดของการพึ่งพา (เช่นจากส่วนต่อประสาน) ในกรณีที่คับปลิ้งคับที่คุณให้การพึ่งพาโดยตรงซึ่งไม่ใช่วิธีการเข้ารหัสที่ดี


2

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


1

หากการสร้าง / การดำรงอยู่ของวัตถุขึ้นอยู่กับวัตถุอื่นซึ่งไม่สามารถปรับแต่งได้การมีเพศสัมพันธ์อย่างแน่นหนา และหากการพึ่งพาสามารถปรับแต่งการมีเพศสัมพันธ์หลวมของมัน ลองพิจารณาตัวอย่างใน Java:

class Car {

    private Engine engine = new Engine( "X_COMPANY" ); // this car is being created with "X_COMPANY" engine
    // Other parts

    public Car() { 
        // implemenation 
    }

}

ไคลเอนต์ของCarคลาสสามารถสร้างด้วยเครื่องมือ "X_COMPANY" เท่านั้น

ลองพิจารณาการแต่งงานกันครั้งนี้ด้วยความสามารถในการเปลี่ยนแปลงสิ่งต่อไปนี้:

class Car {

    private Engine engine;
    // Other members

    public Car( Engine engine ) { // this car can be created with any Engine type
        this.engine = engine;
    }

}

ตอนนี้ a Carไม่ได้ขึ้นอยู่กับเอ็นจิ้นของ "X_COMPANY" เนื่องจากสามารถสร้างได้ด้วยประเภท

บันทึกย่อเฉพาะของ Java: การใช้อินเทอร์เฟซ Java เพียงเพื่อ de-coupling ไม่ใช่วิธีการออกแบบที่เหมาะสม ใน Java อินเทอร์เฟซมีจุดประสงค์ - เพื่อทำหน้าที่เป็นสัญญาซึ่งเป็นการแสดงพฤติกรรม / ความได้เปรียบโดยไม่ตั้งใจ

ข้อคิดเห็นของ Bill Rosmus ในคำตอบที่ยอมรับมีคำอธิบายที่ดี


0

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

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

    class A {
       public int a = 0;
       public int getA() {
          System.out.println("getA() method");
          return a;
       }
       public void setA(int aa) {
          if(!(aa > 10))
             a = aa;
       }
    }
    public class B {
       public static void main(String[] args) {
          A aObject = new A();
          aObject.a = 100; // Not suppose to happen as defined by class A, this causes tight coupling.
          System.out.println("aObject.a value is: " + aObject.a);
       }
    }

In the above example, the code that is defined by this kind of implementation uses tight coupling and is very bad since class B knows about the detail of class A, if class A changes the variable 'a' to private then class B breaks, also class A's implementation states that variable 'a' should not be more than 10 but as we can see there is no way to enforce such a rule as we can go directly to the variable and change its state to whatever value we decide.

    Output
    aObject.a value is: 100

Loose Coupling
Loose coupling is a design goal to reduce the inter-dependencies between components of a system with the goal of reducing the risk that changes in one component will require changes in any other component.
Loose coupling is a much more generic concept intended to increase the flexibility of the system, make it more maintainable and makes the entire framework more stable.
Example:

class A {
   private int a = 0;
   public int getA() {
      System.out.println("getA() method");
      return a;
   }
   public void setA(int aa) {
      if(!(aa > 10))
         a = aa;
   }
}
public class B {
   public static void main(String[] args) {
      A aObject = new A();
      aObject.setA(100); // No way to set 'a' to such value as this method call will
                         // fail due to its enforced rule.
      System.out.println("aObject value is: " + aObject.getA());
   }
}

ในตัวอย่างข้างต้นรหัสที่กำหนดโดยการใช้งานประเภทนี้ใช้การเชื่อมต่อแบบหลวมและแนะนำให้ใช้เนื่องจากคลาส B ต้องผ่านคลาส A เพื่อรับสถานะที่มีการบังคับใช้กฎ หากคลาส A ถูกเปลี่ยนแปลงภายในคลาส B จะไม่แตกเนื่องจากใช้คลาส A เท่านั้นเป็นวิธีการสื่อสาร

Output
getA() method
aObject value is: 0
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.