ทำไมการส่งวัตถุผ่านวิธีการแบบคงที่จะได้เปรียบ?


9

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

เพื่อชี้แจงสิ่งที่ฉันหมายถึงพิจารณาชั้นเรียนต่อไปนี้:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public void incrementValue() {
        someValue++;
    }
}

เปรียบเทียบกับการใช้ทางเลือกนี้ด้วยวิธีการคงที่:

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public static void incrementValue(SomeClass obj) {
        obj.someValue++;
    }
}

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


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

13
@NathanMerrill ฉันคิดว่าคุณไม่มีจุด เขาถามว่าเคยมีสถานการณ์ที่การสร้างและใช้วิธีที่สองแทนที่จะเป็นวิธีแรกจะดีกว่าไหม

@Mego ไม่เพียง แต่วิธีการที่กำหนดในตัวอย่าง; ฉันถามว่ามีช่วงเวลาใดเมื่อใช้วิธีการคงที่และการส่งผ่านวัตถุจะดีกว่าวิธีการโทรบนวัตถุ
Addison Crump

สมมุติว่าคุณขอ Java เป็นพิเศษ?
enderland

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

คำตอบ:


34

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


1
ตัวอย่างเช่น: String.Compare ใน C # (ผมคิดว่ามีบางสิ่งบางอย่างที่คล้ายกันใน Java)
edc65

Objects.equals () และ Objects.compare () เป็นตัวอย่างใน Java - แต่ไม่ได้อยู่ในคลาสดั้งเดิม อย่างน้อยในไลบรารีมาตรฐาน Java มันเป็นเรื่องธรรมดาที่จะมีวิธีการอินสแตนซ์ในบางสิ่งบางอย่างเช่นวัตถุ แต่แล้ววิธีการคงที่ในชั้นเรียนของวัตถุ
daboross

20

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

ในกรณีทั่วไปฉันสามารถนึกถึงเหตุผลสองสามข้อที่วิธีสแตติกอาจเหมาะสม:

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

  • คุณกำลังส่งวัตถุสองชิ้นขึ้นไปและต้องการเน้นว่าวัตถุเหล่านั้นมีความสำคัญเท่ากัน

  • null เป็นค่าที่ถูกต้อง (ตามที่อธิบายโดยผู้ใช้ 9000)


5

มันจะเป็นการดีที่จะรวมวิธีการที่เปลี่ยนสถานะของวัตถุเป็นวิธีการอินสแตนซ์แทนที่จะเป็นวิธีการคงที่

อย่างไรก็ตามเราสามารถหาตัวอย่างของวิธีการคงที่ซึ่งเป็นpureวิธีการและนำวัตถุเป็นอินพุตเช่นเมื่อเราต้องการยกตัวอย่างวัตถุตามกฎการตรวจสอบบางอย่าง ตัวอย่างเช่น. NETมีวิธีDateTime.TryParse(String s, DateTime d)การตรวจสอบและยกตัวอย่างวัตถุ แต่พารามิเตอร์มีการทำเครื่องหมายอย่างชัดเจนว่าDateTime dout

อีกกรณีหนึ่งได้เมื่อเราเปรียบเทียบวัตถุและต้องการที่จะได้รับวัตถุที่ต้องการเป็นค่าตอบแทนมากกว่าค่าบูลีน / Team.GetHigherScorer(teamA, teamB).IncreaseRanking()จำนวนเต็มของผลการเปรียบเทียบตัวอย่างเช่น สิ่งนี้จะสะอาดกว่า:

int compareResult = teamA.compareScoreWith(teamB);
if (compareResult == 1)
    teamA.IncreaseRanking();
else if (compareResult == -1) 
    teamB.IncreaseRanking();

(ปล่อยให้กรณี "วาด" ออกมาเพื่อความเรียบง่าย)


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

1
ฉันทิ้งคำว่า "ทั้งหมด" จากคำพูดของฉันมันทำให้สับสน ฉันไม่เคยคาดหวังประสิทธิภาพหรือขนาดคำตอบนั้นขึ้นอยู่กับการเขียนโปรแกรม อย่างไรก็ตามoutเป็น.Netคำหลักที่ใช้เป็นตัวแก้ไขพารามิเตอร์ มันระบุว่าพารามิเตอร์จะถูกส่งผ่านโดยการอ้างอิง ดูรายละเอียดmsdn.microsoft.com/en-us/library/t3c3bfhx.aspx
wonderbell

4
ประโยคแรกนั้นผิด ถ้าเรามีclass C { int x; static void M() { แล้ว M xเป็นอย่างดีสามารถที่จะเข้าถึง ตัวอย่างเช่นint y = (new C()).x;ถูกกฎหมาย
Eric Lippert

@EricLippert :) ฉันแน่ใจว่าคุณรู้ว่าฉันหมายถึงอะไร มันวิเศษที่อาจารย์สามารถอ่านระหว่างบรรทัดได้ ฉันอาจจะต้องแก้ไขประโยคนั้น เพื่อความกระจ่างบางสิ่งเช่นนี้ static void M() { this.x = 1; }เป็นไปไม่ได้
wonderbell

1
@wonderbell: ไม่ฉันแน่ใจว่าฉันไม่ทราบว่าคุณหมายถึงอะไร ฉันรู้ว่าคุณเขียนอะไร ฉันทราบว่าthis.xผิดเพราะxไม่สามารถเข้าถึงได้ แต่เพราะthisไม่มีอยู่ มันไม่ได้เป็นคำถามของการเข้าถึงที่ทุกคนจะเป็นคำถามของการดำรงอยู่
Eric Lippert

4

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

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