CodeGym /จาวาบล็อก /สุ่ม /กฎการเข้ารหัส: พลังของชื่อที่ถูกต้อง ความคิดเห็นที่ดีและไ...
John Squirrels
ระดับ
San Francisco

กฎการเข้ารหัส: พลังของชื่อที่ถูกต้อง ความคิดเห็นที่ดีและไม่ดี

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

ชื่อที่ถูกต้อง

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

จากละครทีวีเรื่อง "Sherlock" (2553-2560)

การตั้งชื่ออินเทอร์เฟซ

อินเทอร์เฟซมักมีชื่อที่ขึ้นต้นด้วยอักษรตัวใหญ่และเขียนด้วย CamelCase เมื่อเขียนอินเทอร์เฟซ การเพิ่มคำนำหน้า "I" เพื่อกำหนดให้เป็นอินเทอร์เฟซ (เช่น IUserService) ถือเป็นแนวปฏิบัติที่ดี แต่นั่นดูน่าเกลียดและทำให้เสียสมาธิ ในกรณีเช่นนี้ เป็นการดีกว่าที่จะละคำนำหน้า (UserService) และเพิ่ม "Impl" ต่อท้ายชื่อการใช้งาน (เช่น UserServiceImpl) หรืออาจเป็นทางเลือกสุดท้าย เพิ่มคำนำหน้า "C" ต่อชื่อของการใช้งาน (เช่น CUserService)

ชื่อชั้น

เช่นเดียวกับอินเทอร์เฟซ ชื่อคลาสจะใช้ตัวพิมพ์ใหญ่และใช้ CamelCase ไม่สำคัญว่าเรากำลังเผชิญกับวันสิ้นโลกจากซอมบี้ ไม่สำคัญว่าจุดจบจะอยู่ใกล้แค่เอื้อม — ไม่ควร ไม่ควร ชื่อของชั้นเรียนควรเป็นคำกริยา! ชื่อคลาสและอ็อบเจกต์ต้องเป็นนามหรือนามประสม (UserController, UserDetails, UserAccount และอื่นๆ) คุณไม่ควรใส่ตัวย่อของแอปพลิเคชันต่อท้ายชื่อของแต่ละคลาส เนื่องจากจะเพิ่มความซับซ้อนโดยไม่จำเป็น ตัวอย่างเช่น หากเรามีแอปพลิเคชันการย้ายข้อมูลผู้ใช้ โปรดอย่าเพิ่ม "UDM" ลงในแต่ละคลาส เช่น UDMUserDetails, UDMUserAccount, UDMUserController

ชื่อเมธอด

โดยปกติแล้ว ชื่อเมธอดจะขึ้นต้นด้วยอักษรตัวพิมพ์เล็ก แต่ก็ยังใช้รูปแบบตัวพิมพ์อูฐ (camelCase) ข้างต้น เรากล่าวว่าชื่อคลาสไม่ควรเป็นคำกริยา ในกรณีนี้ สถานการณ์ตรงกันข้าม: ชื่อของเมธอดควรเป็นคำกริยาหรือวลีกริยา: findUserById, findAllUsers, createUser และอื่นๆ เมื่อสร้างเมธอด (เช่นเดียวกับตัวแปรและคลาส) ดังนั้นให้ใช้หลักการตั้งชื่อที่สอดคล้องกันเพื่อหลีกเลี่ยงความสับสน ตัวอย่างเช่น หากต้องการค้นหาผู้ใช้ อาจตั้งชื่อเมธอด getUserById หรือ findUserById และอีกสิ่งหนึ่ง: อย่าใช้อารมณ์ขันในชื่อวิธีการ เพราะคนอื่นอาจไม่เข้าใจเรื่องตลก เป็นผลให้พวกเขาอาจไม่เข้าใจว่าวิธีการนี้ใช้ทำอะไร

ชื่อตัวแปร

ในกรณีส่วนใหญ่ ชื่อตัวแปรจะขึ้นต้นด้วยอักษรตัวพิมพ์เล็กและยังใช้ camelCase ยกเว้นเมื่อตัวแปรเป็นค่าคงที่ส่วนกลาง ในกรณีเช่นนี้ ตัวอักษรทั้งหมดของชื่อจะเขียนด้วยตัวพิมพ์ใหญ่และคั่นคำด้วยเครื่องหมายขีดล่าง ("_") เพื่อความสะดวก คุณสามารถใช้บริบทที่มีความหมายเมื่อตั้งชื่อตัวแปร กล่าวอีกนัยหนึ่ง เมื่อมีตัวแปรเป็นส่วนหนึ่งของสิ่งที่ใหญ่กว่า เช่น ชื่อ นามสกุล หรือสถานะ ในกรณีเช่นนี้ คุณสามารถเพิ่มคำนำหน้าที่ระบุอ็อบเจ็กต์ที่เป็นของตัวแปรนี้ได้ ตัวอย่างเช่น userFirstName, userLastName, userStatus คุณควรหลีกเลี่ยงชื่อที่คล้ายกันสำหรับตัวแปรเมื่อมีความหมายต่างกันโดยสิ้นเชิง ต่อไปนี้เป็นคำตรงข้ามที่พบบ่อยซึ่งใช้ในชื่อตัวแปร:
  • เริ่มต้น/สิ้นสุด
  • ที่ผ่านมาเป็นครั้งแรก
  • ล็อค/ปลดล็อค
  • นาที/สูงสุด
  • ถัดไป/ก่อนหน้า
  • เก่า/ใหม่
  • เปิด/ปิด
  • มองเห็น/มองไม่เห็น
  • ที่มา/เป้าหมาย
  • ต้นทาง/ปลายทาง
  • ขึ้นลง

ชื่อตัวแปรแบบสั้น

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

public User findLastUser() {
   return findAllUsers().stream()
           .sorted((x, y) -> -x.getCreatedDate().compareTo(y.getCreatedDate()))
           .findFirst()
           .orElseThrow(() -> new ResourceNotFoundException("No user exists"));
}
ที่นี่เราใช้ตัวแปรชื่อสั้น x และ y เพื่อจัดเรียงสตรีม จากนั้นเราก็ลืมมันไป

ความยาวที่เหมาะสมที่สุด

มาว่ากันต่อที่หัวข้อความยาวของชื่อ ความยาวชื่อที่เหมาะสมที่สุดอยู่ระหว่าง n ถึง maximumNumberOfUsersInTheCurrentGroup กล่าวอีกนัยหนึ่ง ชื่อสั้น ๆ นั้นขาดความหมาย ในขณะที่ชื่อที่ยาวเกินไปจะทำให้โปรแกรมยาวขึ้นโดยไม่เพิ่มความสามารถในการอ่าน และเราก็ขี้เกียจเกินไปที่จะเขียนทุกครั้ง นอกเหนือจากกรณีที่อธิบายไว้ข้างต้นสำหรับตัวแปรที่มีชื่อสั้น เช่น n คุณควรมีความยาวประมาณ 8-16 ตัวอักษร นี่ไม่ใช่กฎที่เข้มงวด เป็นเพียงแนวทางเท่านั้น

ความแตกต่างเล็กน้อย

ฉันไม่สามารถพลาดที่จะพูดถึงความแตกต่างเล็กน้อยในชื่อ นี่เป็นวิธีปฏิบัติที่ไม่ดีเช่นกัน เนื่องจากความแตกต่างเหล่านี้อาจทำให้สับสนหรือต้องใช้เวลามากเป็นพิเศษในการสังเกต ตัวอย่างเช่น ความแตกต่างระหว่าง InvalidDataAccessApiUsageException และ InvalidDataAccessResourceUsageException เป็นเรื่องยากที่จะมองเห็นได้อย่างรวดเร็ว ความสับสนอาจเกิดขึ้นได้บ่อยๆ เมื่อใช้ตัวพิมพ์เล็ก L และ O เนื่องจากอาจถูกเข้าใจผิดว่าเป็น 1 และ 0 ได้ง่าย ในบางฟอนต์จะเห็นความแตกต่างได้ชัดเจนกว่า แต่บางฟอนต์ก็น้อยกว่า

ความหมาย

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

ข้อมูลบิดเบือน

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

ค้นหา

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

ความคิดเห็น

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

ประเภทของความคิดเห็น

  • ความคิดเห็นทางกฎหมาย — ความคิดเห็นที่จุดเริ่มต้นของไฟล์ต้นฉบับแต่ละไฟล์ด้วยเหตุผลทางกฎหมาย ตัวอย่างเช่น:

    
    * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
    * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
    

  • ความคิดเห็นที่ให้ข้อมูล — ความคิดเห็นที่แสดงคำอธิบายของรหัส (ให้ข้อมูลเพิ่มเติมหรืออธิบายถึงความตั้งใจของส่วนที่กำหนดของรหัส)

    ตัวอย่างเช่น:

    
    /*
    * Combines the user from the database with the one passed for updating
    * When a field in requestUser is empty, it is filled with old data from foundUser
    */
    private User mergeUser(User requestUser, User foundUser) {
           return new User(
           foundUser.getId(),
           requestUser.getFirstName() == null ? requestUser.getFirstName() : foundUser.getFirstName(),
           requestUser.getMiddleName() == null ? requestUser.getMiddleName() : foundUser.getMiddleName(),
           requestUser.getLastName() == null ? requestUser.getLastName() : foundUser.getLastName(),
           requestUser.getAge() == null ? requestUser.getAge() : foundUser.getAge()
           );
           }
    

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

  • คำเตือนความคิดเห็น — ข้อคิดเห็นมีจุดประสงค์เพื่อเตือนนักพัฒนารายอื่นเกี่ยวกับผลที่ตามมาที่ไม่พึงประสงค์ของการกระทำ (เช่น เตือนพวกเขาเกี่ยวกับสาเหตุที่การทดสอบถูกทำเครื่องหมายเป็น @Ignore):

    
    // Takes too long to run
    // Don't run if you don't have a lot of time
    @Ignore
    @Test
    public void someIntegrationTest() {
           ……
           }
    

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

    ตัวอย่างจะเป็น:

    
    // TODO: Add a check for the current user ID (when the security context is created)
    
    @Override
    public Resource downloadFile(File file) {
           return fileManager.download(file);
           }
    

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

  • เสริมความคิดเห็น — แสดงความคิดเห็นเน้นความสำคัญของสถานการณ์ที่มองแวบแรกอาจดูเหมือนไม่มีนัยสำคัญ

    ตัวอย่างเช่น พิจารณาส่วนหนึ่งของวิธีการที่เติมฐานข้อมูลทดสอบด้วยสคริปต์บางตัว:

    
    Stream.of(IOUtils.resourceToString("/fill-scripts/" + x, StandardCharsets.UTF_8)
           .trim()
           .split(";"))
           .forEach(jdbcTemplate::update);
    // The trim() call is very important. It removes possible spaces at the end of the script
    // so that when we read and split into separate requests, we don't end up with empty ones
    

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

    ต่อไปนี้คือตัวอย่างวิธีการทั่วไปในการอัปเดตผู้ใช้:

    
    /**
    * Updates the passed fields for a user based on its id.
         *
    * @param id id of the user to be updated
    * @param user user with populated fields for updating
    * @return updated user
    */
           User update(Long id, User user);
    

ความคิดเห็นที่ไม่ดี

  • ความคิดเห็นพึมพำ — ความคิดเห็นที่มักจะเขียนอย่างเร่งรีบและมีความหมายเฉพาะสำหรับนักพัฒนาที่เขียนถึงเท่านั้นที่เข้าใจได้ เนื่องจากมีเพียงเขาหรือเธอเท่านั้นที่รับรู้ถึงสถานการณ์ที่เหมาะสมยิ่งที่ความคิดเห็นนั้นอ้างถึง

    พิจารณาตัวอย่างนี้:

    
    public void configureSomeSystem() {
           try{
           String configPath = filesLocation.concat("/").concat(CONFIGURATION_FILE);
           FileInputStream stream = new FileInputStream(configPath);
           } catch (FileNotFoundException e) {
           // If there is no configuration file, the default configuration is loaded 
          }
    }
    

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

  • ความคิดเห็นที่ซ้ำซ้อน — ความคิดเห็นที่ไม่มีภาระทางความหมายใดๆ เนื่องจากสิ่งที่เกิดขึ้นในส่วนที่กำหนดของโค้ดนั้นมีความชัดเจนอย่างมาก กล่าวอีกนัยหนึ่งความคิดเห็นนั้นอ่านง่ายกว่าโค้ด

    ลองดูตัวอย่าง:

    
    public class JdbcConnection{
    public class JdbcConnection{
       /**
        * The logger associated with the current class
        */
       private Logger log = Logger.getLogger(JdbcConnection.class.getName());
    
       /**
        * Creates and returns a connection using the input parameters
        */
       public static Connection buildConnection(String url, String login, String password, String driver) throws Exception {
           Class.forName(driver);
           connection = DriverManager.getConnection(url, login, password);
           log.info("Created connection with db");
           return connection;
       }
    

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

  • ความคิดเห็นที่ไม่น่าเชื่อถือ — ความคิดเห็นที่ไม่จริงและทำให้เข้าใจผิดเท่านั้น (ข้อมูลบิดเบือน) ตัวอย่างเช่นนี่คือหนึ่ง

    
    /**
    * Helper method. Closes the connection with the scanner if isNotUsing is true
    */
    private void scanClose(Scanner scan, boolean isNotUsing) throws Exception {
       if (!isNotUsing) {
           throw new Exception("The scanner is still in use");
       } scan.close();
    }
    

    มีอะไรผิดปกติกับความคิดเห็นนี้? ข้อเท็จจริงที่ว่ามันโกหกเราเล็กน้อยโดยที่การเชื่อมต่อถูกปิดหาก isNotUsing เป็นเท็จ ไม่ใช่ในทางกลับกัน ตามที่ความคิดเห็นแจ้งเรา

  • ข้อคิดเห็นที่จำเป็น — ข้อคิดเห็นที่ถือเป็นข้อบังคับ (เช่น ข้อคิดเห็น Javadoc) แต่ในความเป็นจริงแล้วบางครั้งอาจกองพะเนินมากเกินไปและไม่น่าเชื่อถือและไม่จำเป็น (คุณต้องพิจารณาว่าข้อคิดเห็นเหล่านี้จำเป็นจริงๆ หรือไม่)

  • ตัวอย่าง:

    
    /**
    * Create a user based on the parameters
    * @param firstName first name of the created user
    * @param middleName middle name of the created user
    * @param lastName last name of the created user
    * @param age age of the created user
    * @param address address of the created user
    * @return user that was created
    */
    User createNewUser(String firstName, String middleName, String lastName, String age, String address);
    

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

  • บันทึกความคิดเห็น — ความคิดเห็นที่บางครั้งถูกเพิ่มไปยังส่วนเริ่มต้นของโมดูลทุกครั้งที่มีการแก้ไข (เช่น บันทึกการเปลี่ยนแปลง)

    
    /**
    * Records kept since January 9, 2020;
    **********************************************************************
    * 9 Jan 2020: Providing a database connection using JDBC Connection;
    * 15 Jan 2020: Adding DAO-level interfaces for working with the database;
    * 23 Jan 2020: Adding integration tests for the database;
    * 28 Jan 2020: Implementation of DAO-level interfaces;
    * 1 Feb 2020: Development of interfaces for services,
    * in accordance with the requirements specified in user stories;
    * 16 Feb 2020: Implementation of service interfaces
    * (implementation of business logic related to the work of the database);
    * 25 Feb 2020: Adding tests for services;
    * 8 Mar 2020: Celebration of International Women's Day (Terry is drunk again);
    * 21 Mar 2020: Refactoring the service layer;
    */
    

    แนวทางนี้เคยชอบธรรม แต่ด้วยการกำเนิดของระบบควบคุมเวอร์ชัน (เช่น Git) มันกลายเป็นความยุ่งเหยิงและความซับซ้อนของโค้ดโดยไม่จำเป็น

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

    
    * @author Bender Bending
    

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

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

    
    //    public void someMethod(SomeObject obj) {
    //    .....
    //    }
    

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

  • ความคิดเห็นที่ไม่ชัดเจน — ความคิดเห็นที่อธิบายบางสิ่งบางอย่างด้วยวิธีที่ซับซ้อนเกินไป

    
    /*
        * Start with an array large enough to store
        * all the data bytes (plus filter bytes) with a cushion, plus 300 bytes
        * for header data
        */
    this.dataBytes = new byte[(this.size * (this.deep + 1) * 2)+300];
    

    ความคิดเห็นควรอธิบายรหัส ตัวมันเองไม่ควรต้องการคำอธิบาย แล้วเกิดอะไรขึ้นที่นี่? "กรองไบต์" คืออะไร? "+1" นั้นเกี่ยวกับอะไร ทำไมต้อง 300?

หากคุณได้ตัดสินใจเขียนความคิดเห็นแล้ว ต่อไปนี้คือเคล็ดลับสองสามข้อ:
  1. ใช้สไตล์ที่ดูแลรักษาง่าย: การรักษาสไตล์ที่หรูหราและแปลกใหม่เกินไปนั้นน่ารำคาญและใช้เวลานาน
  2. อย่าใช้ความคิดเห็นท้ายบรรทัดที่อ้างถึงบรรทัดเดียว: ผลลัพธ์คือความคิดเห็นจำนวนมาก ยิ่งไปกว่านั้น การคิดความคิดเห็นที่มีความหมายสำหรับแต่ละบรรทัดเป็นเรื่องยาก
  3. เมื่อคุณเขียนความคิดเห็น พยายามตอบคำถามว่า "ทำไม" ไม่ใช่ "อย่างไร"
  4. หลีกเลี่ยงข้อมูลที่ย่อ ดังที่ฉันได้กล่าวไว้ข้างต้น เราไม่ต้องการคำอธิบายสำหรับความคิดเห็น: ความคิดเห็นคือคำอธิบาย
  5. คุณสามารถใช้ความคิดเห็นเพื่อจดบันทึกหน่วยและช่วงค่า
  6. วางความคิดเห็นใกล้กับรหัสที่พวกเขาอธิบาย
สุดท้ายนี้ ฉันยังคงต้องการเตือนคุณว่าความคิดเห็นที่ดีที่สุดไม่ใช่ความคิดเห็น แต่เป็นการใช้การตั้งชื่ออย่างเชี่ยวชาญตลอดทั้งแอปพลิเคชันของคุณ ตามกฎแล้ว เวลาส่วนใหญ่เราจะทำงานกับโค้ดที่มีอยู่ บำรุงรักษาและขยายโค้ด จะสะดวกกว่ามากเมื่อโค้ดนี้อ่านและเข้าใจได้ง่าย เนื่องจากโค้ดที่ไม่ดีจะเป็นอุปสรรค มันเหมือนกับการขว้างประแจในการทำงาน และความรีบร้อนเป็นเพื่อนที่ซื่อสัตย์ของมัน และยิ่งเรามีรหัสที่ไม่ดีมากเท่าไหร่ประสิทธิภาพก็ยิ่งลดลงเท่านั้น ซึ่งหมายความว่าเราจำเป็นต้องปรับโครงสร้างใหม่เป็นครั้งคราว แต่ถ้าตั้งแต่แรกคุณพยายามเขียนโค้ดที่จะไม่ทำให้นักพัฒนาคนต่อไปต้องการค้นหาและฆ่าคุณ คุณก็ไม่จำเป็นต้องปรับโครงสร้างใหม่บ่อยนัก แต่ก็ยังมีความจำเป็นเนื่องจากเงื่อนไขและข้อกำหนดของผลิตภัณฑ์เปลี่ยนแปลงตลอดเวลาด้วยการเพิ่มการพึ่งพาและการเชื่อมต่อใหม่ ฉันคิดว่านั่นคือทั้งหมดสำหรับฉันในวันนี้ ขอบคุณทุกคนที่อ่านมาถึงตรงนี้ :)
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION