วิธีการกำหนดระดับของสิ่งที่เป็นนามธรรม


35

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

คำถามของฉันคือเกณฑ์ในการกำหนดระดับของสิ่งที่เป็นนามธรรมคืออะไร?

ฉันพูดย่อหน้าจากหนังสือ:

เพื่อให้แน่ใจว่าฟังก์ชั่นของเรากำลังทำ“ สิ่งเดียว” เราต้องตรวจสอบให้แน่ใจว่าข้อความในฟังก์ชั่นของเรานั้นอยู่ในระดับเดียวกันของนามธรรม มันง่ายที่จะดูว่ารายการ 3-1 ละเมิดกฎนี้อย่างไร มีแนวคิดที่มีอยู่ในระดับที่สูงมากของนามธรรมเช่น getHtml (); อื่น ๆ ที่อยู่ในระดับปานกลางของ abstraction เช่น: String pagePathName = PathParser.render (pagePath); และยังคงอยู่ในระดับต่ำอย่างน่าทึ่งเช่น:. append ("\ n")


คำตอบ:


27

ผู้เขียนอธิบายว่าในส่วน "การอ่านรหัสจากบนลงล่าง" ของส่วนที่พูดถึงเกี่ยวกับ abstractions (เหมืองเยื้องลำดับชั้น):

[... ] เราต้องการให้สามารถอ่านโปรแกรมราวกับว่ามันเป็นชุดของย่อหน้าTOแต่ละอันจะอธิบายถึงระดับปัจจุบันของสิ่งที่เป็นนามธรรมและการอ้างอิงที่ตามมาถึงย่อหน้าในระดับถัดไป

  • ในการรวมการตั้งค่าและการฉีกขาดเรารวมการตั้งค่าจากนั้นเรารวมเนื้อหาของหน้าทดสอบแล้วรวมการฉีกขาด
    • หากต้องการรวมการตั้งค่าเราจะรวมการตั้งค่าชุดหากเป็นชุดแล้วเราจะรวมการตั้งค่าปกติ
      • ในการรวมการตั้งค่าชุดข้อมูลเราค้นหาลำดับชั้นของผู้ปกครองสำหรับหน้า "SuiteSetUp" และเพิ่มคำสั่ง include ด้วยเส้นทางของหน้านั้น
        • เพื่อค้นหาผู้ปกครอง ...

รหัสที่ใช้ควบคู่กับสิ่งนี้จะเป็นดังนี้:

public void CreateTestPage()
{
    IncludeSetups();
    IncludeTestPageContent();
    IncludeTeardowns();
}

public void IncludeSetups()
{
    if(this.IsSuite())
    {
        IncludeSuiteSetup();
    }

    IncludeRegularSetup();
}

public void IncludeSuiteSetup()
{
    var parentPage = FindParentSuitePage();

    // add include statement with the path of the parentPage
}

และอื่น ๆ ทุกครั้งที่คุณลงลึกถึงลำดับชั้นของฟังก์ชันคุณควรเปลี่ยนระดับของนามธรรม ในตัวอย่างข้างต้นIncludeSetups, IncludeTestPageContentและIncludeTeardownsทุกคนในระดับเดียวกันของนามธรรม

ในตัวอย่างที่ให้ไว้ในหนังสือผู้เขียนแนะนำว่าฟังก์ชั่นใหญ่ควรแบ่งออกเป็นฟังก์ชั่นขนาดเล็กที่มีความเฉพาะเจาะจงมากและทำสิ่งเดียวเท่านั้น หากทำถูกต้องฟังก์ชัน refactored จะมีลักษณะคล้ายกับตัวอย่างที่นี่ (เวอร์ชัน refactored ให้ไว้ในรายการ 3-7 ในหนังสือ)


10

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

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

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

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

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

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


2

คำถามของฉันคือเกณฑ์ในการกำหนดระดับของสิ่งที่เป็นนามธรรมคืออะไร?

ระดับนามธรรมควรจะชัดเจน เป็นนามธรรมถ้าเป็นส่วนหนึ่งของโดเมนปัญหา - ไม่ใช่ส่วนหนึ่งของภาษาการเขียนโปรแกรม เป็นการยากที่จะชัดเจนยิ่งขึ้นกว่า "abstract นามธรรม" == "ไม่จริง" == "โดเมนปัญหา" และ "ไม่ใช่นามธรรม == คอนกรีต == ส่วนหนึ่งของภาษา" มันควรจะเป็นเรื่องเล็กน้อยที่จะตัดสินใจในระดับที่เป็นนามธรรม ไม่ควรมีความละเอียดใด ๆ เลย

.append("\n")ไม่เป็นนามธรรม มันแค่ใส่ตัวอักษรลงบนสตริง นั่นจะเป็นรูปธรรม ไม่เป็นนามธรรม

String pagePathName = PathParser.render(pagePath);ข้อตกลงกับสตริง สิ่งที่เป็นรูปธรรม ส่วนหนึ่งของคุณสมบัติการเขียนโปรแกรมภาษาที่เป็นรูปธรรม บางส่วนทำงานกับแนวคิด "พา ธ " และ "parser" ที่เป็นนามธรรม

getHtml(); นามธรรม. ข้อตกลงกับ "มาร์กอัป" และสิ่งต่าง ๆ ที่ไม่ใช่เรื่องง่ายภาษารูปธรรม

บทคัดย่อ == ไม่ใช่คุณสมบัติภาษา

คอนกรีต == คุณสมบัติภาษา


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

1

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

foreach(var customer in allCustomers)
{
    if (CustomerIsChanged(customer)
        customer.Save();
}

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

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