คุณค่าในการซ่อนรายละเอียดผ่านทาง abstractions คืออะไร ความโปร่งใสมีค่าหรือไม่


30

พื้นหลัง

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

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

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

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

เกิดอะไรขึ้นที่นี่? ทุกระบบที่ฉันเคยทำงานออกแบบมาไม่ดี (จากมุมมองนี้อย่างน้อย) หรือไม่?

ปรัชญาของฉัน

เมื่อฉันพัฒนาซอฟต์แวร์ฉันรู้สึกว่าฉันพยายามทำตามปรัชญาที่ฉันรู้สึกว่าเกี่ยวข้องกับปรัชญาของ ArchLinux :

Arch Linux ยังคงความซับซ้อนโดยธรรมชาติของระบบ GNU / Linux ในขณะที่ยังคงความเป็นระเบียบและโปร่งใส ผู้พัฒนาและผู้ใช้ Arch Linux เชื่อว่าการพยายามซ่อนความซับซ้อนของระบบจริง ๆ แล้วจะส่งผลให้เกิดระบบที่ซับซ้อนยิ่งขึ้นดังนั้นจึงควรหลีกเลี่ยง

ดังนั้นฉันไม่เคยพยายามซ่อนความซับซ้อนของซอฟต์แวร์ไว้เบื้องหลังเลเยอร์สิ่งที่เป็นนามธรรม ฉันพยายามละเมิดสิ่งที่เป็นนามธรรมไม่ใช่เป็นทาสของสิ่งนั้น

คำถามที่หัวใจ

  1. การซ่อนรายละเอียดมีคุณค่าหรือไม่?
  2. เราไม่เสียสละความโปร่งใสหรือไม่
  3. ความโปร่งใสนี้มีค่าหรือไม่?

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

4
ฉันคิดว่ามีคำถามที่ดีอยู่ในนั้นอย่างไรก็ตามมันอ่านมากเหมือนการพูดจาโผงผางต่อสิ่งที่เป็นนามธรรม คุณอาจจะไม่เน้นย้ำเรื่องนั้นและนำคำถามที่แท้จริงออกมาเพิ่มเติม
PersonalNexus

4
คุณแน่ใจหรือไม่ว่าคุณกำลังใช้คำจำกัดความที่ถูกต้องของ "ซ่อนรายละเอียด"? ในบริบทนี้มันเกี่ยวกับการลดการแต่งงานไม่ใช่การป้องกันคุณจากการเรียนรู้การทำงานภายในของบางสิ่ง
Andres F.

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

8
ฉันคิดว่าสิ่งที่คุณกำลังประสบกับปัญหาไม่ใช่สิ่งที่เป็นนามธรรมมันเป็นเลเยอร์ทางอ้อมที่ว่างเปล่าซึ่งไม่เป็นนามธรรมอะไรเลย ใช่สิ่งเหล่านี้มักพบได้ในระบบองค์กรขนาดใหญ่และไม่ดี
Michael Borgwardt

คำตอบ:


47

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

ลองนึกภาพว่าคุณมีรายการวัตถุและแต่ละวัตถุมีNameคุณสมบัติและข้อมูลอื่น ๆ และหลายครั้งคุณต้องค้นหารายการในรายการที่Nameตรงกับสตริงที่แน่นอน

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

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

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


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

3
@ User606723: มันควรจะเป็น แต่นั่นไม่ได้หมายความว่ามันมักจะเป็น บางคนไม่เข้าใจประเด็นและพวกเขาก็กองซ้อนกันบนชั้นมากกว่าและเปลี่ยนเป็นระเบียบ นี่คือเหตุผลที่โปรแกรมเมอร์ที่มีประสบการณ์แนะนำให้นักพัฒนารุ่นใหม่ไม่เคยใช้เทคโนโลยีหรือเทคนิคใหม่จนกว่าพวกเขาจะเข้าใจ
Mason Wheeler

3
@ user606723: ความโปร่งใสส่งเสริมการมีเพศสัมพันธ์อย่างแน่นหนาดังนั้นในขณะที่อาจไม่เลวเสมอไป แต่มักจะเป็น
Malfist

3
ปัญหาที่เมสันอธิบายเกี่ยวกับคนที่ซ้อนอยู่บนเลเยอร์ในรูปแบบของการเขียนโปรแกรมสินค้าลัทธิคือเหตุผลที่ฉันสงสัยเกี่ยวกับการรับมรดกมากเกินไป ดูเหมือนว่าโดยเฉพาะจะเป็นปัญหาสำหรับโปรแกรมเมอร์ Java
jhocking

2
ไม่การมีเพศสัมพันธ์แน่นไม่ได้เลวร้ายเสมอไป บ่อยครั้งที่มันไม่ดี แต่มีความยาวมาก ๆ เพื่อหลีกเลี่ยงปัญหาที่อาจทำให้เกิดปัญหาที่เลวร้ายยิ่งขึ้นเช่นการเข้ารหัสแบบอ่อน
Mason Wheeler

16

ฉันเพิ่งอ่านหัวข้อใน Code Complete เกี่ยวกับสิ่งที่เป็นนามธรรมดังนั้นจึงเป็นที่มาของแหล่งข้อมูลส่วนใหญ่นี้

จุดสำคัญคือการลบความต้องการที่จะถามว่า เมื่อคุณโทรuser.get_id()คุณจะรู้ว่าidสิ่งนั้นคือสิ่งที่คุณจะได้รับ หากคุณต้องถามว่า "สิ่งนี้จะได้รับรหัสผู้ใช้?" คุณอาจไม่ต้องการidหรือget_id()ส่งคืนสิ่งที่ไม่คาดคิดและออกแบบมาไม่ดี

คุณใช้นามธรรมเพื่ออนุญาตให้คุณออกแบบ:

a house with doors and windows

ไม่ได้ออกแบบ

a box with four walls,
    with 3 holes,
        two of which fit panes of glass surrounded by wood frames,
        one that fits a large plank of wood with hinges and a metal knob,
etc.

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

9
@ user606723 จากนั้นคำถามของคุณเกี่ยวกับการออกแบบที่ซับซ้อนมากกว่าเป็นนามธรรม
Andres F.

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

ควรปิดคำถามนี้หรือเปลี่ยนชื่อ
Jake Berger

8

การซ่อนรายละเอียดมีคุณค่าหรือไม่?

ใช่. โดยการนำเสนอ abstractions เราสามารถคิดและโปรแกรมในระดับที่สูงขึ้น

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

มนุษย์มีความจำในการทำงาน จำกัด สิ่งที่เป็นนามธรรมช่วยให้เราสามารถให้เหตุผลเกี่ยวกับระบบขนาดใหญ่

Aren't we sacrificing transparency?

ไม่ได้หากไม่ได้ใช้ abstractions วัตถุประสงค์ของส่วนประกอบซอฟต์แวร์จะถูกฝังในรายละเอียดซ้ำ ๆ นักพัฒนาใช้จ่ายวันของพวกเขาลุยผ่านรหัสเช่นนี้:

for (i = 0; i < pilgrim.wives.size(); ++i) {
  wife = pilgrim.wives[i];
  for (j = 0; j < wife.sacks.size(); ++j) {
     sack = wife.sacks[i];
     for (k = 0; j < sack.cats.size(); ++j) {
        cat = sack.cats[k];
        for (m = 0; m < cat.kits.size(); ++m) {
           ++count;
        }
     }
  }
}

และคิดว่า "โอ้ใช่อีกวงสี่ระดับเหนือชุด" แทนที่จะมอง

pilgrim.kits.each { ++count; }

ความโปร่งใสนี้มีค่าหรือไม่?

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


7

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

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

  • เมื่อคุณค้นหาและแก้ไขข้อบกพร่องมีแนวโน้มที่จะมีอยู่ในอินสแตนซ์ที่คัดลอกวางของรหัสที่คล้ายกันอื่น ๆ ดังนั้นนอกเหนือจากการค้นหาและแก้ไขข้อบกพร่องแล้วคุณยังต้องออกไปค้นหาเหตุการณ์อื่นและแก้ไขด้วย
  • เพื่อที่จะหาข้อผิดพลาดหรือใช้การเปลี่ยนแปลงโปรแกรมเมอร์บำรุงรักษาจะต้องสามารถเข้าใจรหัสที่เกี่ยวข้อง ความยากในการทำเช่นนี้จะเพิ่มขึ้นตามขนาดของส่วนรหัสที่เกี่ยวข้อง แต่ยิ่งมีขอบเขตมากขึ้น การรักษาตัวแปรครึ่งโหลไว้ในหัวของคุณในขณะที่การใช้รหัสบางอย่างในใจสามารถทำได้ แต่ถ้าคุณมีสองสามร้อยคนผลผลิตของคุณจะได้รับผลกระทบอย่างรุนแรง (ฉันชอบเปรียบเทียบกระบวนการคิดกับโปรแกรมที่ไม่มี RAM จริงและต้องจุ่มลงใน swapfile: แทนที่จะอ่านรหัสอย่างคล่องแคล่วในครั้งเดียว โปรแกรมเมอร์ต้องข้ามไปมาเพื่อค้นหาสิ่งต่าง ๆ )
  • ขอบเขตของชิ้นส่วนของรหัสยังส่งผลกระทบต่อขนาดของ codebase ที่ต้องขุดผ่านเพื่อหาจุดบกพร่อง หากคุณมีฟังก์ชั่นสิบบรรทัดที่มีพารามิเตอร์สองตัวและไม่มีค่ากลมและคุณรู้ค่าของอินพุตและบรรทัดที่มันเกิดปัญหาการค้นหาบั๊กมักจะไม่สำคัญและมักจะไม่ต้องการอะไรมากไปกว่าการดูโค้ด หากเป็นสองสามร้อยบรรทัดพารามิเตอร์ยี่สิบห้ารอบและเรียกใช้ฟังก์ชั่นอื่น ๆ ที่มีลักษณะคล้ายกันคุณจะรู้สึกเจ็บปวดอย่างหนัก
  • หากไม่มีนามธรรมที่เหมาะสมการเปลี่ยนแปลงใด ๆ ที่อาจส่งผลกระทบต่อส่วนใหญ่ของ codebase เนื่องจากในทางปฏิบัติสิ่งใดก็ตามอาจขึ้นอยู่กับรหัสที่จะเปลี่ยนแปลง อาการโดยทั่วไปที่มีรหัสฐานคือคุณทำการเปลี่ยนแปลงเล็กน้อยดูไร้เดียงสาและคุณลักษณะที่ไม่เกี่ยวข้องอย่างสมบูรณ์ก็เกิดขึ้นทันที ด้วยสิ่งที่เป็นนามธรรมคุณสามารถ จำกัด จำนวนความเสียหายที่สามารถทำได้และคุณสามารถคาดการณ์ได้มากขึ้น หากคุณเปลี่ยนชื่อของฟิลด์ส่วนตัวคุณจะมีไฟล์ต้นฉบับเพียงไฟล์เดียวที่จะตรวจสอบ หากคุณเปลี่ยนชื่อของตัวแปรทั่วโลกคุณจะต้องเรียกใช้รหัสฐานทั้งหมด

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


2

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

เมื่อคุณตั้งนาฬิกาปลุกบนนาฬิกาที่คุณมั่นใจว่าจะใช้งานได้คุณสามารถนอนหลับได้เพราะรู้ว่ามันจะดับในเวลาที่ถูกต้อง ตื่นก่อนเวลาหนึ่งชั่วโมงเพื่อให้คุณสามารถดูวินาทีที่ติ๊กไปนั้นเป็นการสิ้นเปลือง


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

1
คุณเห็นการเปลี่ยนแปลงรหัสสำหรับทุกเฟรมเวิร์กที่คุณเคยใช้หรือไม่
JeffO

1
ไม่ แต่ฉันไม่ได้ดูแลการเปลี่ยนแปลงรหัสสำหรับทุกเฟรมเวิร์กที่ฉันเคยใช้
user606723

3
คุณได้พิสูจน์ประเด็นของเจฟโอแล้ว: คุณไม่ได้อยู่ในการดูแลรักษานาฬิกาปลุกเช่นกัน หากคุณซื้อและเริ่มใช้งานโดยไม่ต้องทำการฉีกขาดและวิเคราะห์ว่ามันทำงานอย่างไรคุณยอมรับว่าอวัยวะภายในจะเป็นนามธรรมสำหรับคุณ ไม่มีอะไรบอกว่าคุณไม่สามารถฉีกมันออกจากกันเพื่อค้นหาว่ามันทำงานอย่างไร แต่บ่อยครั้งที่คุณพบว่ามันจำเป็น?
Blrfl

2

เพื่อตอบคำถามของคุณโดยเฉพาะ:

การซ่อนรายละเอียดมีคุณค่าหรือไม่?

ใช่. ตามที่คุณรับทราบในบรรทัดแรกของคำถามของคุณ

เราไม่เสียสละความโปร่งใสหรือไม่

ไม่ได้จริงๆ การเขียนอย่างดีจะทำให้ง่ายต่อการเข้าใจรายละเอียดหากจำเป็น

ความโปร่งใสนี้มีค่าหรือไม่?

ใช่. ควรออกแบบและนำบทคัดย่อมาใช้เพื่อให้เข้าใจรายละเอียดได้ง่ายเมื่อต้องการ / ต้องการ


ในที่สุดคำตอบที่ฉันชอบ
user606723

1

ฉันจะบอกว่าการซ่อนรายละเอียดนั้นยอดเยี่ยมเมื่อสิ่งที่ซ่อนอยู่นั้นใช้งานได้

ตัวอย่างเช่นสมมติว่าเราพัฒนาส่วนต่อประสานที่กำหนดลักษณะการทำงาน (เช่น GetListItems, SendListItem) ซึ่งเป็นคุณลักษณะสองอย่างที่ผู้ใช้เริ่มต้นผ่านการคลิกปุ่มหรือบางอย่าง .. ตอนนี้ผู้ใช้แต่ละคนสามารถมี "ListItemStore" ของตัวเอง .. ตัวหนึ่งบน Facebook คนที่อยู่ใน myspace .. (ตัวอย่าง) .. และบอกว่ามันถูกบันทึกเป็นคุณสมบัติผู้ใช้ / การตั้งค่าบางอย่างในแอปผ่านทางผู้ใช้ prefrences .. และบอกว่าเป็นไปได้สำหรับนักพัฒนาแอปที่จะเพิ่ม ListItemStore เพิ่มเติม เวลา (mybook, facespace, ฯลฯ .. )

ตอนนี้มีรายละเอียดมากมายในการเชื่อมต่อกับ Facebook และรับรายการ .. และมีรายละเอียดเท่ากันเมื่อเชื่อมต่อกับ myspace .. และอื่น ๆ

ตอนนี้หลังจากเขียนรหัส "เข้าถึงร้านค้า" เริ่มต้นแล้วอาจไม่จำเป็นต้องแก้ไข (ในกรณีของ facebook เราอาจต้องมีนักพัฒนาเต็มเวลาเพื่อติดตามการเปลี่ยนแปลง zing .. ),

ดังนั้นเมื่อคุณใช้รหัสมันคล้ายกับ:

    new ItemManager(user) //passes in user, allowing class to get all user properties
    ItemManager.GetListItems()

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

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


ใช่ แต่ส่วนที่ต้องบำรุงรักษาไม่เคยเป็นสองบรรทัด สิ่งเหล่านี้เป็นไปไม่ได้ที่จะทำให้งง เป็นระดับที่ 2, 3 และ 4 เสมอที่คุณต้องเปลี่ยน ฉันจะยอมรับว่านี่เป็นสิ่งที่ดีเมื่อคุณมี API คุณสามารถเชื่อถือได้ว่าจะมีเสถียรภาพแต่ถ้าหากความซับซ้อนของธุรกิจของคุณนั้นไม่เสถียร
user606723

1
@ user606723 ถ้า API ของคุณไม่เสถียรก็มีแนวโน้มที่จะยังไม่บรรลุนิติภาวะหรือมีแนวโน้มที่จะเกิดสิ่งที่ไม่ถูกต้อง
sdg

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

@sdg หรือเนื่องจากความต้องการของระบบมีการเปลี่ยนแปลงอยู่เสมอ เนื่องจากกฎหมายมีการเปลี่ยนแปลงเนื่องจากการเปลี่ยนแปลงของ API อื่น ๆ มันอยู่นอกเหนือการควบคุมของเรา
user606723

1
@ user606723 - ฉันทำงานบนระบบ SaaS ทางการเงินจริง ๆ และฉันเห็นข้อผิดพลาดของการไม่มีนามธรรมเพียงพอทุกรอบการเปิดตัว บางส่วนเป็นผลมาจากการออกแบบที่ไม่ดี แต่โดยปกติแล้วจะเป็นผลมาจากการผลักโค้ดในตำแหน่งที่ไม่ได้ตั้งใจไว้ แต่แรก จะลงห่วงโซ่จะเจ็บปวดไม่มีความเห็นชื่อและencapsulation ถ้าทั้งหมดที่ฉันต้องทำคือ Remeasurements.GetRemeasureType (Grant) และจากนั้น reMeasure.PerformCalc () ที่จะดีกว่าการเพิ่มโอเวอร์โหลดและอ่านผ่านสาขาตรรกะที่แตกต่างกันเพื่อมาถึงการคำนวณที่เหมาะสมหรือเพิ่มอันใหม่
hanzolo

1

สิ่งที่คุณอ้างถึงว่า "ซ่อน" หลายคนมองว่าเป็นข้อกังวล (เช่นการนำไปใช้กับส่วนต่อประสาน)

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

หากรหัสการนำไปปฏิบัตินั้นงงงวยฉันจะเห็นว่าเป็นอุปสรรคต่อความโปร่งใส แต่สิ่งที่เป็นนามธรรมที่ฉันเห็นมันเป็นเพียงองค์กรที่ดี


1

ก่อนอื่นสิ่งใดที่นอกเหนือจากคำสั่งรหัสเครื่องเดียวก็เป็นสิ่งที่เป็นนามธรรม - while...doloop เป็นวิธีที่เป็นสัญลักษณ์ที่สอดคล้องกันในการเป็นตัวแทนการเปรียบเทียบและการเรียกที่อยู่ที่จำเป็นในการทำซ้ำชุดคำสั่งจนกว่าจะตรงตามเงื่อนไข ในทำนองเดียวกันชนิด int เป็นนามธรรมสำหรับจำนวนบิต X (ขึ้นอยู่กับระบบของคุณ) การเขียนโปรแกรมเป็นเรื่องเกี่ยวกับนามธรรม

คุณอาจเห็นด้วยว่า abstractions ดั้งเดิมเหล่านั้นมีประโยชน์อย่างยิ่ง ดีดังนั้นสามารถสร้างของคุณเอง OOAD และ OOP เป็นเรื่องเกี่ยวกับ

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

รูปแบบการออกแบบที่รู้จักกันดีที่ใช้ในการเขียนโปรแกรม OO นั้นขึ้นอยู่กับนามธรรม ฉันขอแนะนำให้อ่านรูปแบบการออกแบบหัวแรกของฟรีแมนและรูปแบบการออกแบบ Head Firstเพื่อให้ได้ความรู้สึกที่ดีขึ้นว่าทำไมนามธรรมเป็นสิ่งที่ดี


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

จริงเกินไปแม้ว่าจะดูเหมือนเป็นรูปธรรมมากขึ้นในระดับคำสั่งของเครื่อง
Matthew Flynn

1

ฉันคิดว่าฉันเข้าใจความรู้สึกของคุณเกี่ยวกับเรื่องนี้และฉันคิดว่าฉันมีความคิดเห็นที่คล้ายกัน

ฉันได้ทำงานกับนักพัฒนา Java ที่เปลี่ยนคลาสบรรทัดรหัส 50 เป็น 3 คลาสและอินเทอร์เฟซ 3 เนื่องจากง่ายต่อการเข้าใจ และฉันก็ทนไม่ไหว

สิ่งที่ยากต่อการเข้าใจแทบจะเป็นไปไม่ได้ในการแก้ไขข้อบกพร่องและไม่จำเป็นต้อง "สลับการใช้งาน"

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

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

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


1

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

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

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


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


0

ในหลายกรณีคุณไม่จำเป็นต้องรู้ว่าจะใช้งานอย่างไร ฉันเกือบจะรับประกันได้ว่าคุณจะเขียนโค้ดแบบนี้people.Where(p => p.Surname == "Smith")วันละหลายครั้ง แต่คุณแทบจะไม่เคยคิดว่า "วิธีนี้Where()ใช้งานได้จริงอย่างไร" คุณไม่แคร์ - คุณรู้ว่าวิธีการนี้อยู่ที่นั่นและมันทำให้คุณได้ผลลัพธ์ที่คุณต้องการ ทำไมคุณถึงสนใจว่ามันทำงานอย่างไร

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

มีข้อยกเว้นสำหรับกฎนี้แน่นอน (มันจะไม่เป็นกฎโดยไม่มีใครจะทำ!) และนั่นคือถ้ามีข้อผิดพลาดในวิธีการ ดังนั้นในตัวอย่างข้างต้นหากคุณมีรายการที่มี 3 คนอยู่ในนั้นและคุณรู้ว่าหนึ่งในนั้นมีนามสกุล Smith และพวกเขาไม่ได้ถูกส่งกลับในรายการจากนั้นคุณสนใจเกี่ยวกับการดำเนินการของวิธีการนั้น .

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


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

ปัญหาคือPeopleFactory.People.Strategy.MakePeople.(CoutryLaw.NameRegistry.NameMaker.Make()) as People.Female
Coder

@ user606723 คุณไม่ต้องสนใจรหัสทุกบรรทัดในรหัสฐานของคุณตลอดเวลา หากมีข้อผิดพลาดในการใช้งานหรือมีการตั้งค่าสถานะว่าจำเป็นต้องเขียนใหม่ (เนื่องจากช้าเขียนไม่ดีหรืออะไรก็ตาม) และคุณกำลังเขียนอีกครั้งคุณก็สนใจมัน ไม่เช่นนั้นควรเก็บให้พ้นทาง บางทีปัญหาของคุณคือคุณพยายามเป็นเจ้าของรหัสตลอดเวลา คุณควรจดจ่อกับรหัสที่คุณกำลังทำอยู่ในช่วงเวลาหนึ่งในความคิดของฉัน
Stuart Leyland-Cole

@Coder เห็นได้ชัดว่าเป็นรูปแบบที่ค่อนข้างมากของนามธรรม! ตอนแรกฉันคิดว่ามันเป็นสิ่งที่ OP ต่อต้าน แต่จากการอ่านคำตอบที่เหลือของพวกเขาดูเหมือนว่าพวกเขาเห็นสิ่งที่เป็นนามธรรมเลวร้ายเลวร้าย นี่คือเหตุผลที่ฉันพยายามอธิบายระดับต่าง ๆ ของสิ่งที่เป็นนามธรรมในคำตอบของฉัน
Stuart Leyland-Cole

0

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

ความคิดเหล่านั้นแสดงออกผ่านกฎหมายสำคัญสามข้อในสถาปัตยกรรมซอฟต์แวร์:

กฎของ Simon: "ลำดับชั้นลดความซับซ้อน" (ลำดับชั้นแนะนำสิ่งที่เป็นนามธรรม)

กฎหมายของ Parna: "สิ่งที่ซ่อนอยู่เท่านั้นที่สามารถเปลี่ยนแปลงได้โดยไม่มีความเสี่ยง"

กฎหมายของคอนสแตนติน: โปรแกรมที่แข็งแกร่งจำเป็นต้องมีเพศสัมพันธ์ต่ำและมีการติดต่อกันสูง


"ลำดับชั้นลดความซับซ้อน" - ไม่จำเป็นต้องเป็นเรื่องจริง
Coder

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

0

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

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

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

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

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

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


0

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

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

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

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

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

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


0

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

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

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

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

ตัวอย่างเช่น: การใช้ abstraction ของคลาส Socket ใน Java ฉันแน่ใจว่ารหัสแอปพลิเคชันของฉันจาก Java 1.2 ยังคงทำงานได้ดีภายใต้ Java 7 (แม้ว่าจะมีการเปลี่ยนแปลงประสิทธิภาพ) ตั้งแต่ Java 1.2 มีลูกค้าใหม่จำนวนมากที่ใช้นามธรรมนี้เช่นกัน

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

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

การอ้างอิงถึง ArchLinux เหมาะสมกับฉันถ้าคุณพิจารณา "ภายใน" ของระบบปฏิบัติการว่าเป็นการใช้งานที่ซับซ้อนของสิ่งที่เป็นนามธรรมซึ่งเป็นระบบปฏิบัติการของแอปพลิเคชันที่ทำงานอยู่ ทำให้มันง่ายในความกล้าของนามธรรม


0

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

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

หลักการพื้นฐานเหล่านี้เป็นหลักการสำคัญที่อยู่เบื้องหลังการห่อหุ้มและสิ่งที่เป็นนามธรรม ความรู้เกี่ยวกับวิธีการที่วัตถุทำในสิ่งที่มันไม่ควรจะเป็นสิ่งจำเป็นในการใช้มันเพื่อทำสิ่งที่มันทำ แม้ในการเขียนโปรแกรมคอมพิวเตอร์รายละเอียดของเส้นทางไฟฟ้าภายใน CPU ที่รันโปรแกรมของคุณนั้นได้รับการสรุปไว้เบื้องหลังอย่างน้อยครึ่งชั้นของคำแนะนำ I / O ไดร์เวอร์ซอฟต์แวร์ OS และรันไทม์ วิศวกรซอฟต์แวร์ที่ประสบความสำเร็จจำนวนมากเขียนโค้ดที่ดีอย่างสมบูรณ์แบบโดยไม่ต้องกังวลเกี่ยวกับสถาปัตยกรรมฮาร์ดแวร์ที่แน่นอนหรือแม้แต่ระบบปฏิบัติการบิลด์ที่จะรัน รวมฉันด้วย.

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

Abstraction อนุญาตให้ "สิ่งนี้ไม่เหมือนกัน แต่เนื่องจากทั้งสองเป็น XI สามารถใช้พวกเขาได้ตามที่ฉันต้องการ X" หากวัตถุของคุณสืบทอดหรือใช้สิ่งที่เป็นนามธรรมผู้บริโภคของคุณควรคาดหวังว่าการใช้งานของคุณจะให้ผลลัพธ์ที่เหมือนหรือคล้ายกันกับการใช้งานอื่น ๆ ที่เป็นที่รู้จักของสิ่งที่เป็นนามธรรม Toyota Camry และ Ford Fusion นั้นเป็นทั้ง "รถยนต์" เช่นนี้พวกเขามีชุดของฟังก์ชั่นที่คาดหวังเช่นพวงมาลัย เลี้ยวทวนเข็มนาฬิการถเลี้ยวซ้าย หมุนตามเข็มนาฬิการถไปทางขวา คุณสามารถเข้าไปในรถใด ๆ ในสหรัฐอเมริกาและคาดหวังว่ารถจะมีพวงมาลัยและคันเหยียบอย่างน้อยสองคันคันที่อยู่ด้านขวาเป็นคัน "รถไป" และคนที่อยู่ตรงกลางเป็นคัน "หยุดรถ" .

ข้อพิสูจน์ของสิ่งที่เป็นนามธรรมคือ "ทฤษฎีความประหลาดใจอย่างน้อยที่สุด" หากคุณอยู่หลังพวงมาลัยของรถใหม่เพื่อทดสอบขับหมุนพวงมาลัยตามเข็มนาฬิกาและรถเลี้ยวซ้ายคุณจะประหลาดใจที่พูดน้อยที่สุด คุณจะกล่าวหาว่าดีลเลอร์ของ peddling POS และไม่น่าจะฟังเหตุผลของเขาว่าทำไมพฤติกรรมใหม่นั้น "ดีกว่า" มากกว่าที่คุณคุ้นเคยหรือพฤติกรรมนี้เป็น "เอกสาร" หรืออย่างไร " โปร่งใส "ระบบควบคุมคือ แม้จะมีรถใหม่นี้และรถอื่น ๆ ที่คุณเคยขับยังคงเป็น "รถยนต์" แต่เมื่อคุณขับรถคันนี้คุณต้องเปลี่ยนแนวคิดพื้นฐานเกี่ยวกับวิธีการขับเคลื่อนรถยนต์เพื่อที่จะขับรถใหม่ให้ประสบความสำเร็จ โดยทั่วไปนั้นเป็นสิ่งที่ไม่ดี และมันจะเกิดขึ้นก็ต่อเมื่อมีข้อได้เปรียบที่ง่ายต่อกระบวนทัศน์ใหม่ บางทีการเพิ่มเข็มขัดนิรภัยก็เป็นตัวอย่างที่ดี 50 ปีที่แล้วคุณเพิ่งเข้าและออก แต่ตอนนี้คุณต้องคาดเข็มขัดข้อได้เปรียบที่เข้าใจได้ง่ายคือคุณไม่ต้องผ่านกระจกหน้ารถหรือเข้าไปในที่นั่งผู้โดยสารหากคุณประสบอุบัติเหตุ ถึงอย่างนั้นไดรเวอร์ก็ต่อต้าน เจ้าของรถหลายคนตัดเข็มขัดนิรภัยออกจากรถจนกว่ากฎหมายจะผ่านการบังคับใช้

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