การทำซ้ำรหัสกับวิธีที่รับผิดชอบหลายอย่าง


11

ฉันพยายามปฏิบัติตาม Single Responsibility Principle (SRP) และไม่ใช้ Code ซ้ำ อย่างไรก็ตามมักจะมีสถานที่ที่มีการทำซ้ำรหัสที่ไม่มีอะไรมากไปกว่าบล็อคโค้ดของการเรียกใช้ที่สามารถต้านทานการแตกออกเป็นอย่างน้อยแปลความหมายเต็มวิธีการชื่อ:

DoAction1();
DoAction2();

if (value)
    DoAction3();

DoAction4();

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


1
ทำไมพวกเขาถึงต่อต้านถูกแยกออกเป็นวิธีที่มีความหมายที่แตกต่างกัน?
Chandranshu

การกระทำทั้งหมดทำสิ่งที่ไม่เกี่ยวข้อง ฉันจะต้องเขียน: void MethodThatDoAction1ThenAction2AndAction3IfValueAndThenAction4(). ฉันอยากเห็นความหมายเพิ่มเติมใน: CodeBlock1().
yBee

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

1
หากเป็นการปลอบใจผู้ชนะในฤดูใบไม้ผลิสำหรับชื่อชั้นยาวนั้นAbstractInterruptibleBatchPreparedStatementSetterจะมีขนาดเล็กกว่าวิธีการของคุณ
Chandranshu

1
@Chandranshu ฉันเชื่อว่าความคิดเห็นของคุณจะทำงานได้ดีเป็นคำตอบสำหรับคำถามนี้
Simon Forsberg

คำตอบ:


13

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

หากเป็นการปลอบใจผู้ชนะในฤดูใบไม้ผลิสำหรับชื่อชั้นยาวจะมีความยาวAbstractInterruptibleBatchPreparedStatementSetter49 ตัว


11

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

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

ดังที่Chandranshuพูดว่า"ถ้าคุณทำซ้ำความหมาย [... ] นี้และตั้งชื่อให้" คือตรงประเด็นและเหมาะสม

ป้อนคำอธิบายรูปภาพที่นี่

Pic ความอนุเคราะห์: CodeChef Facebook ภาพหน้า


2

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

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

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

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

ฉันมักจะพยายามที่จะรักษา text-editor เหมือนกันชั่วขณะหนึ่งจนกระทั่งฉันสามารถดูว่าสิ่งที่ดูเหมือนว่าจะซ้ำ ๆ จะกลายเป็นมูลค่าแฟ ฉันแค่ทำซ้ำ ๆ แต่ฉันคอยจับตาดูอนาคตของบล็อกนั้นโดยทำให้มันเป็นเรื่องง่ายที่จะจับคู่ในภายหลัง

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

สำหรับฉันแล้วดูเหมือนว่าถ้าผู้คนพยายามแยกแยะสิ่งที่คุณพยายามแยกออกจากกันเราจะมีห้องสมุดที่มีโครงสร้างไร้ค่าทั้งหมดเช่น Do1 จากนั้น 2 ถ้า 2 ปลอม Do1IfTrueDo2

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

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


ฉันชอบส่วนที่แยกสาระสำคัญของการทำซ้ำรหัส: เพื่อลดจำนวนของรหัสที่จะต้องมีการตรวจสอบเมื่อมีการเปลี่ยนแปลงในตรรกะ
yBee

1

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

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

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


1

ฉันมีสถานการณ์ที่อาจคล้ายกับของคุณ:

มีคลาสที่กำหนดฟังก์ชันการทำงานของวัตถุที่แสดง:

class Functionality
{
protected:
void functionA();
void functionB();
...
void functionZ();
}

จากนั้นมีคลาสที่กำหนดเวิร์กโฟลว์สำหรับการดำเนินการระดับสูงที่วัตถุดำเนินการ:

class Workflows: private Functionality
{
    void WorkflowA()
    {
        functionA();

        if (m_bValue) {
            functionB();
        }

        functionC();
    }
    ...
    void WorkflowB();
}

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

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

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