ความหมายของนามธรรมที่รั่วไหล?


90

คำว่า "สิ่งที่เป็นนามธรรมที่รั่วไหล" หมายความว่าอย่างไร (โปรดอธิบายด้วยตัวอย่างฉันมักจะมีปัญหาในการฟังทฤษฎีเพียงอย่างเดียว)



14
คุณอาจต้องการอ่านบทความต้นฉบับของ Joel Spolsky The Law of Leaky Abstractionsซึ่งเท่าที่ฉันรู้คือที่มาของคำนี้
Daniel Pryden

2
คำตอบส่วนใหญ่ของผู้หลอกลวงที่เสนอนั้นเกี่ยวกับอินเทอร์เฟซที่คล่องแคล่ว
David Thornley

@ เดวิด: โพสต์ที่ได้รับการโหวตสูงสุดเป็นอันดับสองตอบว่าสิ่งที่เป็นนามธรรมที่รั่วไหลหมายถึงอะไรและด้วยตัวอย่างที่ยอดเยี่ยม
missingfaktor

4
เมื่อคุณค้นหาคำถามนี้ในอีก 4 ปีต่อมาก็ยากที่จะเดาว่าโพสต์ใดเคยเป็นโพสต์ที่ได้รับการโหวตสูงสุดเป็นอันดับ 2
John Reynolds

คำตอบ:


108

นี่คือตัวอย่างMeatspace :

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

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

เป็นเรื่องที่น่าทึ่งจริงๆ ... เด็กอายุ 16 ปีหรือ 80 ปีสามารถใช้เครื่องจักรที่ซับซ้อนนี้ได้โดยไม่รู้จริงๆว่ามันทำงานอย่างไรภายใน!

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

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


8
ขอบคุณสำหรับตัวอย่าง ดูเหมือนจะไม่มีใครสามารถให้คำอธิบายง่ายๆได้
Sebastian Patten

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

1
Meatspace หมายถึงอะไร? คำอธิบายบุคคล?
brumScouse

1
@brumScouse "meatspace" หมายถึงโลกออฟไลน์ทางกายภาพ มันถูกใช้เพื่อเปรียบเทียบกับโลกออนไลน์บนโลกไซเบอร์ ฉันจะแก้ไขคำตอบของฉันเพื่อรวมลิงก์ไปยังคำจำกัดความ
Mark E.Haase

1
ฉันชอบวิธีที่โพสต์นี้ชี้ให้เห็นว่า "ยังมีการรั่วไหล" ทุกอย่างเกี่ยวกับการย่อขนาด
alaboudi

52

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

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


7
@mehaase ฉันไม่เห็นว่ามันสำคัญอย่างไรว่าสิ่งที่เป็นนามธรรมของคุณรั่วไหลโดยการออกแบบหรือโดยการละเลย ฉันได้ขยายคำตอบพร้อมตัวอย่างและข้อมูลเพิ่มเติมจากบทความที่อ้างอิงเพื่อให้สามารถยืนหยัดได้ด้วยตัวเอง นอกจากนี้ฉันไม่คิดว่า "นามธรรมที่รั่วไหล" จำเป็นต้องเป็นการดูถูกเหยียดหยาม สำหรับฉันมันเป็นเพียงการอธิบายสถานการณ์ที่คุณในฐานะนักพัฒนาซอฟต์แวร์ต้องระมัดระวังมากขึ้นเมื่อทำงานกับสิ่งที่เป็นนามธรรม การออกแบบอาจดีไม่ดีหรือเฉยๆโดยไม่ขึ้นกับ "ความรั่ว"
tvanfosson

13

Wikipedia มีคำจำกัดความที่ดีสำหรับเรื่องนี้

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

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

ตัวอย่างสั้น ๆ คือการปิด C # / VB.Net และไม่สามารถจับพารามิเตอร์อ้างอิง / ออกได้ สาเหตุที่ไม่สามารถจับภาพได้เนื่องมาจากรายละเอียดการใช้งานว่ากระบวนการยกเกิดขึ้นได้อย่างไร นี่ไม่ได้หมายความว่ามีวิธีที่ดีกว่าในการทำเช่นนี้


13

นี่คือตัวอย่างที่คุ้นเคยสำหรับนักพัฒนา. NET: Pageคลาสของ ASP.NET พยายามซ่อนรายละเอียดของการดำเนินการ HTTP โดยเฉพาะการจัดการข้อมูลแบบฟอร์มเพื่อให้นักพัฒนาไม่ต้องจัดการกับค่าที่โพสต์ (เนื่องจากแมปค่าฟอร์มไปยังเซิร์ฟเวอร์โดยอัตโนมัติ การควบคุม)

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

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


เว็บฟอร์มมีก้นบึ้งในถัง สิ่งที่แย่กว่านั้นคือ abstractions ที่ถูกปกคลุมบาง ๆ นั้นทำงานร่วมกับ Http ได้เหมือนกับที่คุณทำงานในกล่องถุงมือ
brumScouse

10

ในทางหนึ่งมันเป็นเรื่องทางทฤษฎีล้วนๆแม้ว่าจะไม่สำคัญก็ตาม

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

นามธรรมที่รั่วไหลคือสิ่งที่ไม่ซ่อนรายละเอียดที่ตั้งใจจะซ่อน ถ้า call string.Length บนสตริง 5 อักขระใน Java หรือ. NET ฉันจะได้รับคำตอบใด ๆ จาก 5 ถึง 10 เนื่องจากรายละเอียดการใช้งานโดยที่ภาษาเหล่านั้นเรียกอักขระนั้นเป็นจุดข้อมูล UTF-16 ซึ่งสามารถแสดงถึง 1 หรือ .5 ของตัวละคร สิ่งที่เป็นนามธรรมได้รั่วไหล การไม่รั่วไหลหมายความว่าการหาความยาวอาจต้องใช้พื้นที่จัดเก็บมากขึ้น (เพื่อเก็บความยาวจริง) หรือเปลี่ยนจาก O (1) เป็น O (n) (เพื่อหาว่าความยาวจริงคืออะไร) ถ้าฉันสนใจเกี่ยวกับคำตอบที่แท้จริง (คุณมักจะไม่เข้าใจจริงๆ) คุณต้องพยายามหาความรู้เกี่ยวกับสิ่งที่เกิดขึ้นจริงๆ

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


2
และคุณทำงานกับ 1 และ 0 เพื่อซ่อนความจริงที่ว่าคุณกำลังทำงานกับอุปกรณ์อิเล็กทรอนิกส์และฟิสิกส์ (ฉันรู้ว่าช้ามาก)
Davy8

7

ฉันจะดำเนินการต่อในการให้ตัวอย่างโดยใช้ RPC

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

ความจริงนั้นแตกต่างกันเนื่องจากมีความแตกต่างอย่างมากระหว่างการเรียกใช้ฟังก์ชันท้องถิ่น (แม้ว่าคุณจะใช้ภาษาที่ตีความช้าที่สุดในโลก) และ:

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

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

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

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

ในท้ายที่สุด RPC เป็นนามธรรมที่ไม่ดีเพราะมันรั่วไหลเหมือนตะแกรงทุกระดับ - เมื่อประสบความสำเร็จและเมื่อล้มเหลวทั้งสองอย่าง


<pim <p> ฉันชอบวิธี Erlang ที่ดีกว่าตรงที่ไม่พยายามซ่อนความแตกต่างระหว่างการเรียกใช้ฟังก์ชันและการส่งข้อความไปยังกระบวนการจนถึงจุดที่ทั้งสองใช้ไวยากรณ์ที่แตกต่างกันมาก และการส่งข้อความกระบวนการระยะไกลนั้นแตกต่างอย่างเห็นได้ชัดจากการส่งกระบวนการภายในแม้ว่าจะใช้ไวยากรณ์ทั่วไปเดียวกันก็ตาม </pimpered
JUST MY ที่ถูกต้อง OPINION

2
นี่เป็นคำตอบเดียวที่เป็นตัวอย่างที่ดี (การอ่านเพื่อความเข้าใจผู้คน) ดังนั้นจึงได้รับ +1 ของฉัน
Mark E Haase

4

ตัวอย่างในdjango ORM หลายต่อหลายตัวอย่าง :

โปรดสังเกตในการใช้ API ตัวอย่างที่คุณต้องบันทึก () อ็อบเจ็กต์บทความพื้นฐาน a1 ก่อนที่คุณจะสามารถเพิ่มอ็อบเจ็กต์ Publication ในแอ็ตทริบิวต์แบบกลุ่มต่อกลุ่ม และสังเกตว่าการอัปเดตแอตทริบิวต์แบบกลุ่มต่อกลุ่มจะบันทึกไปยังฐานข้อมูลที่สำคัญทันทีในขณะที่การอัปเดตแอตทริบิวต์เอกพจน์จะไม่ปรากฏในฐานข้อมูลจนกว่าจะมีการเรียก. save ()

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


3

นามธรรมคืออะไร?

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

ตัวอย่างของ Abstraction: ความซับซ้อนของการบิน 737/747 นั้นอยู่ห่างออกไป

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

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

Abstractions ที่รั่วไหลในตัวอย่าง 737

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

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

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

สิ่งเหล่านั้นไม่ได้เป็นนามธรรมไป หลายสิ่งหลายอย่างเป็นนามธรรมไป แต่ไม่ใช่ทุกสิ่ง นักบินต้องการเพียงแค่กังวลเกี่ยวกับคอพวงมาลัยและอาจมีสิ่งอื่นหนึ่งหรือสองอย่าง สิ่งที่เป็นนามธรรมคือ "รั่ว"

Abstractions ที่รั่วไหลในรหัส

...... รหัสของคุณก็เหมือนกัน หากคุณไม่ทราบรายละเอียดการใช้งานที่สำคัญบ่อยกว่านั้นคุณจะต้องเข้ามุม

นี่คือตัวอย่างในการเข้ารหัส:

ORM เป็นนามธรรมของความยุ่งยากในการจัดการกับแบบสอบถามฐานข้อมูล แต่ถ้าคุณเคยทำสิ่งที่ชอบ:

User.all.each do |user|
   puts user.name # let's print each user's name
end

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


0

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

ตัวอย่างเช่นพิจารณาSQLคำค้นหานี้:

SELECT id, first_name, last_name, age, subject FROM student_details;

และทางเลือกอื่น:

SELECT * FROM student_details;

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

เป็นตัวอย่างที่ไม่สำคัญ แต่ในที่สุดมันก็กลับมาที่คำพูดของ Joel Spolsky:

นามธรรมที่ไม่สำคัญทั้งหมดในระดับหนึ่งรั่วไหล

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


-1

สมมติว่าเรามีรหัสต่อไปนี้ในไลบรารี:

Object[] fetchDeviceColorAndModel(String serialNumberOfDevice)
{
    //fetch Device Color and Device Model from DB.
    //create new Object[] and set 0th field with color and 1st field with model value. 
}

เมื่อผู้บริโภคเรียก API พวกเขาจะได้รับ Object [] ผู้บริโภคต้องเข้าใจว่าฟิลด์แรกของอาร์เรย์ออบเจ็กต์มีค่าสีและฟิลด์ที่สองคือค่าโมเดล ที่นี่สิ่งที่เป็นนามธรรมได้รั่วไหลจากห้องสมุดไปสู่รหัสผู้บริโภค

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

DeviceColorAndModel fetchDeviceColorAndModel(String serialNumberOfTheDevice)
{
    //fetch Device Color and Device Model from DB.
    return new DeviceColorAndModel(color, model);
}

-3

สิ่งที่เป็นนามธรรมที่รั่วไหลเป็นข้อมูลเกี่ยวกับสภาวะห่อหุ้ม ตัวอย่างที่ง่ายมากของนามธรรมที่รั่วไหล:

$currentTime = new DateTime();

$bankAccount1->setLastRefresh($currentTime);
$bankAccount2->setLastRefresh($currentTime);
$currentTime->setTimestamp($aTimestamp);

class BankAccount {
    // ...

    public function setLastRefresh(DateTimeImmutable $lastRefresh)
    {
        $this->lastRefresh = $lastRefresh;
    } }

และวิธีที่ถูกต้อง (ไม่ใช่นามธรรมที่รั่วไหล):

class BankAccount
{
    // ...

    public function setLastRefresh(DateTime $lastRefresh)
    {
        $this->lastRefresh = clone $lastRefresh;
    }
}

รายละเอียดเพิ่มเติมที่นี่

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