클래스의 모든 객체를 추적


9

나는 객체 지향 프로그래밍을 처음 접했고 계속이 문제에 부딪쳤다. (Java로 프로그래밍 중입니다.)이 기본적인 문제처럼 보이기 때문에 이것에 대해 조금 꺼려했습니다.하지만 그것에 대한 정보 나 여기에 대한 질문을 찾을 수 없으며 내가 읽은 교과서 (이 과정은 매우 기본적인 수준)는이 문제에 대해 다루었습니다.

종종 나는 다양한 목적을 위해 그것을 반복하기 위해 만들어진 클래스의 모든 객체를 추적해야합니다. 그들은 현재 프로그램을 작성하는 방식으로 많은 객체가 다른 객체에서만 참조되므로 모든 객체를 참조 할 배열이나 컬렉션이 없습니다.

나는 이것이 OOP에서 매우 기본적인 필요성처럼 보였으므로 이것에 대해 매우 제도화되고 간단한 방법이 있어야한다고 생각합니까? 클래스의 모든 객체에 대해 별도의 목록을 유지하는 것이 일반적입니까?

나는 생성자를 통해 생성 된 모든 새로운 객체가 추가 될 정적 배열이나 컬렉션에 대해 생각했습니다. 그러나 생성자가 상속되지 않기 때문에 하위 클래스에서는 작동하지 않습니까?

나는이 질문에 쉬운 답이 하나도 없다는 것을 알고 있습니다. 나는 누군가가이 주제에 대해 조금 깨달을 수 있기를 바랍니다. 여기에 중앙 지식이 부족한 것 같습니다.


5
추적 및 추적기의보다 구체적인 예가 도움이 될 수 있습니다. 이 문제는 상황, 사용 방법 등에 따라 다양한 방식으로 처리됩니다.
JustinC

2
나는 당신이 잘못된 끝에서 문제에 접근하고 있다고 생각합니다. 주어진 클래스의 모든 인스턴스 목록을 필요로하는 것은 흔하지 않으며, 전혀 관련이없는 컨텍스트에서 생성 된 인스턴스조차도이 목록을 통해 서로 의존하기 때문에 모든 종류의 디자인 문제를 일으킬 수 있습니다.
tdammers

1
"다양한 목적을 위해 그들을 통해"... ...와 같은? 일반적으로 객체에는 하나의 '소유자'(공식 용어가 아니라 프로그램 의미론에 대한 설명)가 있으며 다른 사람이 객체에 대해 '다양한 목적'을 갖는 것은 아닙니다.
AakashM 2016 년

답변:


8

클래스의 모든 인스턴스 목록을 유지 해야하는 이유를 모르겠습니다.

그 객체는 절대로 폐기되지 않기 때문에 메모리 누수가 발생할 수 있습니다. 왜냐하면 다른 클래스가 없으면 목록이 여전히 객체를 참조하기 때문입니다.

그러나 정말로 그 길을 따르고 싶다면 :

  1. 팩토리 패턴을 사용하십시오. 클래스를 인스턴스화하고 객체를 반환하는 메소드가있는 팩토리 클래스입니다. 이렇게하면 인스턴스화를 제어하는 ​​중앙 집중식 지점이 있습니다.
  2. 싱글 톤 패턴을 사용하여 인스턴스를 보유하는 목록을 보유하십시오.
  3. 팩토리는 특정 유형의 각 객체를 생성 한 후 목록에 넣습니다.

그건 그렇고 : 생성자가 상속됩니다.


물론 추적 된 인스턴스 목록에서 인스턴스를 제거하는 "dispose"메소드를 팩토리에 제공 할 수 있습니다. 그러나 명시 적으로 호출하는 방법은 없습니다. 또는 인스턴스에 dispose 메소드를 트리거하는 dispose 메소드를 제공합니다.이 메소드는 단점이 동일하지만 사용자에게 가까워 질수록 실제로 표시 될 가능성이 약간 높습니다.
jwenting

@jwenting 물론 그렇습니다. 그러나 이것은 클래스와 팩토리 사이에 추악하고 불필요한 종속성을 만듭니다. 클래스는 클래스를 생성하는 팩토리에 대해 아무것도 알아야합니다.
Tulains Córdova 2016 년

따라서 공장에 공장에 등록하도록 지시하는 대상이 아닌, 공장이 생성 한 내용을 추적하도록하는 것
jwenting

싱글 톤은 기술적으로 내가 생각하는 모든 인스턴스를 보유 할 것입니다. 하나의 단일 인스턴스.
Rig

3

주목해야한다 약한 참조가 더 이상 다른 곳에서 참조 없을 때 가비지 수집기가 추적 개체를 삭제 할 수 있도록 다른 주어진 솔루션과 함께 사용할 수 있습니다. 이를 통해 객체를 수동으로 처리하거나 추적하는 데주의를 기울이는 다른 코드가 없어도 메모리 누수가 제거됩니다. 해제 된 객체에 대한 참조 알림을 받도록 ReferenceQueue를 제공 ​​할 수 있습니다.

나는 생성자를 통해 생성 된 모든 새로운 객체가 추가 될 정적 배열이나 컬렉션에 대해 생각했습니다. 그러나 생성자가 상속되지 않기 때문에 하위 클래스에서는 작동하지 않습니까?

기본 클래스의 생성자는 파생 클래스의 생성자보다 먼저 호출됩니다. 모든 클래스에는 생성자가 하나 이상 있으며 생성자를 재정의 할 수 없습니다.


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 vs. update).

매우 간단한 시나리오에는 적합하지만 다소 복잡하지만 보통 별도의 관리자 클래스를 만드는 것이 가장 좋습니다.


1
당신은 직접 static ArrayList<ListeStatic> list = new ArrayList<ListeStatic>();stas {..}를 억압하여 쓸 수 있습니다
cl-r

2
Java에서 메소드 이름은 소문자로 시작합니다.uptdateAll(){..;}
cl-r

죄송합니다 ... 공개적으로 자바를 방송 한 지
Kelly Thomas

@KellyThomas 목록에 추가 된 자동차는 목록에서 제외됩니다. 부 자연스럽게 들립니다.
Tulains Córdova 2018 년

1
@ CayetanoGonçalves는 정적 필드로서 모든 인스턴스가 공유하는 하나의 목록입니다.
켈리 토마스

2

문맥을 생각하십시오. 객체를 만들 때 특정 상황에서 생성합니다. 예를 들어, 게임이 외계인을 쏘는 것에 관한 것이라면, 앱은 항상 새로운 외계인 객체를 생성 할 것입니다. 스페이스라는 필드 (메인 UI를 나타내는 클래스 일 수 있음)에 표시됩니다.

Space가 currentAliens라는 속성을 갖는 것은 자연 스럽습니다.이 속성은 사용자가 만든 새 외계인을 추가 할 배열입니다. 사용자가 시공간 구조를 찢어 버리고 모든 외계인을 한 번에 파괴하게하려면 해당 컬렉션을 반복하여 각 객체를 파괴해야합니다.

앱의 다른 부분 (예 : 사용자가 특정 유형의 외계인을 한 번에 삭제하도록 허용 할 수있는 설정 페이지)에서이 외계인 컬렉션에 액세스하려면 설정 컨텍스트가 Space 객체에 액세스 할 수 있어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.