มีข้อเสียจริงในการผูกมัดตนเองหรือไม่


14

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

อย่างไรก็ตามนี่ทำให้ฉันคิดว่าบางทีฉันอาจจะเกิดขึ้นในการปฏิบัติที่ไม่ดีโดยกลับ "นี้" ในวิธีการที่ไม่ควรจะคืนอะไร (เช่น setters)

คำถามของฉันคือ: สามารถใช้การประชุมก่อนหน้านี้ถือได้ว่าเป็นการปฏิบัติที่ไม่ดีหรือการละเมิด? ทำไม? ฉันไม่คิดว่าจะมีข้อบกพร่องในการทำงานหรือมีอะไรบ้าง


2
ดูคำถามนี้เพื่อการสนทนาที่ดีprogrammers.stackexchange.com/questions/48419/…
KeesDijk

@ KeesDijk ขอบคุณฉันแก้ไขคำถามของฉันเล็กน้อยดังนั้นจึงไม่คล้ายกับคำถามนั้นเนื่องจากฉันสนใจวิธีการผูกมัดจากชั้นเรียนเดียวกัน
dukeofgaming

1
ที่ SO พวกเขาบอกฉันว่าการผูกมัดไม่ใช่สำหรับ C ++ - stackoverflow.com/questions/5760551/ … - คุณคิดอย่างไร?
kagali-san

1
@hambra ดูเหมือนว่าคุณจะต้องระมัดระวังเมื่อใช้วิธีการกำหนดสายงานและกำหนดมาตรฐานที่ชัดเจนสำหรับที่
dukeofgaming

คำตอบ:


10

ไม่

ในขณะที่Kent Beckชี้ให้เห็นว่ารหัสถูกอ่านบ่อยกว่าที่เขียนไว้

หากการโยงเมธอดทำให้โค้ดของคุณอ่านง่ายขึ้นให้ใช้เมธอดการโยง


1
หนังสือยอดเยี่ยม .. +1
Rein Henrichs

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

@coredump ดูเหมือนว่า OP ได้รับคำสั่งให้ทำเช่นนั้นแล้ว แต่ฉันคิดว่า Steven แค่พูดอย่างนี้เพราะถ้าการผูกมัดวิธีทำให้อ่านได้ง่ายขึ้น
Panzercrisis

1
@Panzercrisis OP ได้รับคำสั่งให้งดใช้วิธีการผูกมัดเนื่องจากความสะดวกสบายกับความหมาย โดยทั่วไปแล้วคำตอบของสตีเวนบอกว่า "ทำต่อไป" และพิจารณาความสามารถในการอ่านรหัสของ OP ด้วยตัวเองโดยไม่พิจารณาความเห็นหรือความสอดคล้องของทีม เกิดอะไรขึ้นถ้า OP ต้องการเขียนคลาสที่มีอยู่ในโครงการเพื่อให้เหมาะกับรสนิยมของเขาเกี่ยวกับการอ่านรหัส นั่นเป็นวิธีที่ฉันเข้าใจข้อโต้แย้งความสะดวกสบาย / ความหมาย: ควรมีเหตุผล "ทางเทคนิค" ที่จะมีวิธีการผูกมัด (btw อาร์กิวเมนต์ที่ฟังดูเหมือนว่าคนอื่นกำลังทำข้ออ้างสำหรับการตั้งค่าของเขา / เธอ)
coredump

9

ใช่มีข้อเสียคือ

รหัสที่อ่านง่ายนั้นดี แต่ควรระวังว่ารหัสนั้นสื่อสารด้วยเช่นกัน เมื่อเมธอดของวัตถุส่งคืนออบเจกต์เสมอมันจะทำการสื่อสารสองสิ่ง:

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

กรณีการใช้ที่ถูกต้อง: แบบสอบถามฐานข้อมูล Ad Hoc

ไลบรารีคลาสมีอยู่ในเกือบทุกภาษาที่ช่วยให้คุณสามารถสืบค้นฐานข้อมูลโดยไม่ต้องหันไปใช้ SQL แบบตายตัว ใช้ Entity Framework สำหรับ. NET เป็นตัวอย่าง:

DBContext db = new DBContext();
List<Post> posts = db.Posts
    .Where(post => post.Title.Contains("Test"))
    .OrderBy(post => post.DateCreated)
    .ToList();

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

กรณีการใช้งานไม่ถูกต้อง: น้ำตาลในการตั้งค่าคุณสมบัติ

ตอนนี้ลองใช้รูปแบบเดียวกันกับPostคลาส:

public class Post
{
    public string Title { get; set; }
    public DateTime DateCreated { get; set; }
    public string Body { get; set; }

    public Post SetTitle(string title)
    {
        Title = title;

        return this;
    }

    public Post SetDateCreated(DateTime created)
    {
        DateCreated = created;

        return this;
    }

    public Post SetBody(string body)
    {
        Body = body;

        return this;
    }
}

ตอนนี้ลองมาดูกันว่าคุณจะใช้คลาสนี้อย่างไร:

Post post = new Post()
    .SetTitle("Test")
    .SetDateCreated(DateTime.Now)
    .SetBody("Just a test");

เมื่อฉันเห็นรหัสนี้ฉันถามคำถามนี้ทันที: "หลังจากโทรSetBodyแล้วจะทำการสืบค้นฐานข้อมูลหรือไม่ฉันต้องโทรหาวิธีอื่นเพื่อพูดว่า" ฉันเสร็จแล้วหรือยัง "

วิธีการที่ถูกล่ามโซ่โทรอะไรสื่อสารกับรหัสโดยใช้Postชั้นเรียน?

  1. ฉันมีการตั้งค่าที่ซับซ้อน
  2. แต่ละวิธีการเรียกสร้างบนก่อนหน้านี้

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

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

เมื่อเพื่อนร่วมงานของคุณพูดว่า:

อินเทอร์เฟซที่คล่องแคล่วไม่ควรดำเนินการเพียงเพื่อความสะดวก แต่เพื่อความหมาย

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


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

ไม่ใช่แค่ "การกำหนดค่าที่ซับซ้อน" แต่ยังเป็น "การเรียกใช้วิธีถัดไปที่สร้างไว้ก่อนหน้านี้" วิธีการผูกมัดมีการสื่อสารเมตาเกี่ยวกับมันที่ไม่เป็นความจริงเสมอไปกับวัตถุประสงค์ของการเรียน
Greg Burghardt

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

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

1
When an object's methods always return the object, it communicates a couple of things- ฉันคิดว่านี่เป็นความเห็นส่วนตัว เป็นการยากที่จะอ้างว่าทุกคนที่ดูวิธีการที่ถูกล่ามโซ่จะถือว่าเป็นสิ่งเดียวกัน
Sam Dufel

1

ข้อเสียเปรียบหลักคือการสูญเสียความชัดเจน ตัวอย่างเช่น

x.foo();
x.bar();
x.baz();

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

x.foo()
 .bar()
 .baz();

ก่อนอื่นมันไม่ชัดเจนbarและbazดำเนินการกับวัตถุประเภทเดียวกันxเว้นแต่คุณจะรู้ว่าxคลาสนั้นเป็นคลาสเดียวที่มีวิธีการเหล่านั้น แม้ว่าจะเป็นเช่นนั้นก็ยังไม่ชัดเจนว่าวิธีการทำงานxหรือวัตถุใหม่

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


0

พิจารณาองค์ประกอบโวหารทั้งหมดของภาษาการเขียนโปรแกรม (ตรงข้ามกับภาษาเครื่องที่เขียนด้วยมือ) และมันทำให้อาร์กิวเมนต์ "ความหมายของความไม่สะดวกสบาย" อ่อนลง

สิ่งที่เราทำในฐานะวิศวกรนั้นให้ความสะดวกสบายรอบความหมาย

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