ทำไมมีวิธีการคงที่ส่วนตัว?


68

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

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

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


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

2
ตัวอย่างรวดเร็ว - วิธีโรงงานที่ใช้โดยคลาสภายในที่ป้องกันการเรียกใช้โดยคลาสอื่น (คุณต้องผ่านวิธีการจากโรงงานเพื่อรับอินสแตนซ์ของคลาส)

2
@ MattFenwick: คุณควรโพสต์สิ่งนี้เป็นคำตอบ
Doc Brown

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

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

คำตอบ:


70

ลักษณะของการเป็นแบบสแตติกนั้นขึ้นอยู่กับการมองเห็น

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


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

ฉันต้องบอกว่าฉันไม่เคยทำแบบนั้นหรือเห็นพฤติกรรมนั้น สองสามครั้งที่ฉันทำมันเป็นวิธีการช่วยเหลือในการเรียนคงที่สาธารณะ
Miyamoto Akira

1
@corsiKa: ผลข้างเคียงไม่ใช่ปัญหา การทำให้สมาชิกแบบสแตติกของคลาสที่ไม่ใช่ส่วนตัวมีประสิทธิภาพสัญญาว่าเวอร์ชันในอนาคตของคลาสจะรวมวิธีการเดียวกันของชื่อเดียวกันซึ่งทำสิ่งเดียวกัน หากความต้องการเปลี่ยนแปลงและรุ่นอนาคตของการเรียนอาจจะมีความจำเป็นในการใช้วิธีการที่ทำงานไม่ตรงเช่นเดียวปัจจุบันไม่เป็นวิธีการอย่างปลอดภัยเอกชนอาจถูกแทนที่ด้วยหนึ่งที่ดีขึ้นตอบสนองความต้องการใหม่ของการเรียน ในฐานะที่เป็นตัวอย่างง่ายๆสมมติว่าระดับความต้องการวิธีการซึ่งจะใช้เวลาสตริงและดำเนินการแทนเช่น<การ&lt;ฯลฯ เมื่อมันถูกเขียน ...
SuperCat

1
... สายอักขระที่ถูกส่งผ่านจะทราบว่าไม่มีแอมป์แซนด์ใด ๆ และดังนั้นจึงไม่แปลง&เป็น&amp;[หากฉันเขียนรหัสฉันจะแปลง&เป็น&amp;แม้ว่าฉันไม่ได้คาดหวังว่ามันจะจำเป็น แต่สมมติว่า มันไม่] หลังจากนั้นมันก็จะกลายเป็นสิ่งจำเป็นในการจัดการกับเครื่องหมาย แต่วิธีการที่ประชาชนเปลี่ยนไปขยาย&ที่จะ&amp;สามารถทำลายรหัสนอกที่มีประสิทธิภาพของตัวเอง&-to- &amp;เปลี่ยนตัว หากวิธีนั้นเป็นแบบส่วนตัวก็สามารถแก้ไขได้&โดยไม่ก่อให้เกิดปัญหากับโค้ดภายนอก
supercat

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

26

เหตุผลทั่วไปที่เป็นธรรม (ใน Java) สำหรับการเริ่มต้นตัวแปรฟิลด์ที่ไม่เปลี่ยนรูปในตัวสร้างโดยใช้private staticวิธีการง่าย ๆเพื่อลดความยุ่งเหยิงของตัวสร้าง

  • เป็นprivate: คลาสภายนอกไม่ควรดู
  • มันคือstatic: มันสามารถทำการดำเนินการบางอย่างอิสระ1ของสถานะของคลาสโฮสต์

ตัวอย่างที่วางแผนไว้ค่อนข้างดังต่อไปนี้ ...

เช่น:

public class MyClass{
    private final String concatenated;

    public MyClass(String a, String b){
        concatenated = concat(a,b);
    }

    public String getConcatenated(){
       return concatenated;
    }

    /**
    *  Concatenates two Strings as `s1---s2`
    **/
    private static final String concat(String s1, String s2){
        return String.format("%s---%s", s1, s2);
    }
}

1 สมมติว่าไม่มีการโต้ตอบกับstaticตัวแปรอื่น ๆ


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

โปรดทราบว่ามีความเป็นไปได้ของบล็อกการเริ่มต้นคงที่
Franz Ebner

13

กรณีการใช้งานทั่วไปสำหรับprivate staticวิธีการเป็นวิธีการอรรถประโยชน์ซึ่งเป็น

  1. ใช้เพียงหนึ่งคลาสเท่านั้น
  2. ไม่ขึ้นกับสถานะภายในของคลาสนั้น

12

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

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

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

จากนั้น .... (อาจจะตอนนี้อาจจะภายหลังอาจไม่เคย)

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

นอกจากนี้ยังง่ายต่อการแปลงเป็นวิธีอินสแตนซ์ของพารามิเตอร์ตัวใดตัวหนึ่งซึ่งมักเป็นที่ที่โค้ดควรจะเป็น


ฉันชอบคำตอบนี้ แต่คุณมีข้อมูลอ้างอิงล่าสุดสำหรับเรื่องนี้หรือไม่? "และอาจจะเร็วกว่านิดหน่อย"
Magnilex

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

2

ฉันคิดได้อย่างน้อยสองเหตุผลว่าทำไมคุณถึงต้องใช้วิธีส่วนตัวแบบคงที่ในชั้นเรียน

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

2: วิธีการคงที่สาธารณะของคุณมีรูทีนย่อยที่คุณไม่ต้องการเรียกโดยตรง วิธีการนั้นยังคงถูกเรียกใช้โดยไม่มีอินสแตนซ์เพียงแค่ไม่โดยตรง

แน่นอนว่า "มันช่วยให้ชั้นเรียนมีเหตุผล" เป็นเหตุผลที่ดีด้วยตัวของมันเอง


1

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

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

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

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


-1

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

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