การติดตามวัตถุทั้งหมดของชั้นเรียน


9

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

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

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

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

ฉันรู้ว่าคำถามนี้อาจไม่มีคำตอบง่ายๆ ฉันแค่หวังว่าใครบางคนสามารถสอนฉันในเรื่องนี้ได้บ้าง ฉันรู้สึกเหมือนว่าฉันขาดความรู้ที่เป็นศูนย์กลางที่นี่


5
ตัวอย่างที่เฉพาะเจาะจงมากขึ้นของการติดตามและตัวติดตามอาจช่วยได้ ปัญหานี้ได้รับการจัดการหลายวิธีขึ้นอยู่กับบริบทวิธีการใช้งานและอื่น ๆ
JustinC

2
ฉันคิดว่าคุณอาจจะเข้าใกล้ปัญหาจากจุดจบที่ผิด มันไม่ธรรมดามากที่จะต้องการรายการของอินสแตนซ์ทั้งหมดของคลาสที่กำหนดและการมีหนึ่งจะทำให้เกิดปัญหาการออกแบบทุกประเภท (เพราะตอนนี้แม้อินสแตนซ์ที่สร้างขึ้นในบริบทที่ไม่เกี่ยวข้องทั้งหมดขึ้นอยู่กับกันและกันผ่านรายการนี้)
tdammers

1
"วนซ้ำเพื่อวัตถุประสงค์ต่าง ๆ " ... เช่น ... ? โดยทั่วไปวัตถุมี 'เจ้าของ' หนึ่งคน (ไม่ใช่คำที่เป็นทางการ แต่เป็นเพียงคำแถลงเกี่ยวกับความหมายของโปรแกรม) และไม่มีใครมี 'จุดประสงค์ที่หลากหลาย' กับวัตถุ
AakashM

คำตอบ:


8

ฉันไม่รู้ว่าทำไมคุณต้องเก็บรายการของคลาสทั้งหมด

นั่นจะทำให้หน่วยความจำรั่วเนื่องจากวัตถุเหล่านั้นจะไม่ถูกกำจัดเนื่องจากรายการจะยังคงถูกอ้างอิงถึงหลังจากไม่มีคลาสอื่นทำ

แต่ถ้าคุณต้องการติดตามเส้นทางนั้นจริงๆ:

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

โดยวิธีการ: ก่อสร้างได้รับมรดก


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

@ jwenting แน่นอนว่าเป็นวิธี แต่นั่นจะสร้างการพึ่งพาที่ไม่น่าเกลียดระหว่างคลาสและโรงงาน ชั้นเรียนไม่ควรรู้อะไรเกี่ยวกับโรงงานที่สร้างพวกเขา
Tulains Córdova

ดังนั้นการมีโรงงานติดตามสิ่งที่สร้างขึ้นแทนที่จะบอกให้โรงงานลงทะเบียน ...
jwenting

เทคนิคเดี่ยวจะระงับทุกกรณีที่ฉันเดา อินสแตนซ์หนึ่งเดียว
Rig

3

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

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

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


2

เมื่อทำเกมคนบางครั้งต้องการคอลเลกชัน "การจัดการตนเอง" ของแต่ละประเภทของวัตถุเกม

การใช้งานอย่างหนึ่งมีลักษณะเช่นนี้:

public class Car {

    static ArrayList<Car> list = new ArrayList<Car>();

    public Car() {
        list.add(this);
    }

    void kill() {
        list.remove(this);
    }

    static public void updateAll()
    {
        for (int i = list.size() - 1; i >= 0; i--)
        {
                list.get(i).update();
        }
    }

    public void update()
    {
        //update logic
    }
}

ในลักษณะนี้วิธีการจัดการคอลเลกชันสามารถประกาศคงที่ในขณะที่วิธีการที่ไม่คงที่จัดการกับอินสแตนซ์ (updateAll เทียบกับการปรับปรุง)

ในขณะที่ดีสำหรับสถานการณ์ที่ง่ายมากโดยมีความซับซ้อนปานกลางก็ควรสร้างคลาสผู้จัดการแยกต่างหาก


1
คุณสามารถเขียนstatic ArrayList<ListeStatic> list = new ArrayList<ListeStatic>();ans ได้โดยตรงเพื่อควบคุม statc {.. }
cl-r

2
ในชื่อวิธีการของจาวาเริ่มต้นด้วยตัวอักษรพิมพ์เล็ก:uptdateAll(){..;}
cl-r

อุ๊ปส์ ... มันเป็นเวลานานแล้วที่ฉันได้ออกอากาศจาวาของฉันในที่สาธารณะ
Kelly Thomas

@KellyThomas รถเพิ่มตัวเองลงในรายการพวกเขาลบตัวเองจากมัน ฟังดูแปลกประหลาด
Tulains Córdova

1
@ CayetanoGonçalvesเป็นฟิลด์แบบสแตติกมันเป็นหนึ่งรายการที่แชร์โดยอินสแตนซ์ทั้งหมด
Kelly Thomas

2

พยายามคิดบริบท เมื่อคุณสร้างวัตถุคุณจะต้องทำในบางบริบท ตัวอย่างเช่นหากเกมของคุณเกี่ยวกับการถ่ายภาพมนุษย์ต่างดาวแอปของคุณจะสร้างวัตถุต่างด้าวใหม่ตลอดเวลา พวกเขาจะแสดงในฟิลด์ที่เรียกว่า Space (ซึ่งอาจเป็นคลาสที่แสดงถึง UI หลัก)

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

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

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