Vraag Is het een slechte gewoonte om elementen toe te voegen aan lijst met behulp van de methode getter in java?


Stel dat ik een private ArrayList of a LinkedList in een klas, dat ik er nooit een nieuwe verwijzing naar zal toewijzen, of met andere woorden, dit zal nooit gebeuren:

myLinkedList = anotherLinkedList;

Zodat ik niet hoeft te gebruiken setMyLinkedList(anotherLinkedList).

Maar! Ik moet er elementen aan toevoegen, of elementen ervan verwijderen.

  • Moet ik een nieuw soort schrijven setter om alleen de taak van te doen adding in plaats van setting, graag willen myLinkedList.add(someElement)?

  • Of het is OK om dit te doen door te gebruiken getter, zonder ongehoorzaam te zijn Encapsulation principal?

    getMyLinkedList().add(someElement)

(+ Stel dat ik mijn stempel ga verliezen als ik encapsulation niet gehoorzaam: - ")


15
2017-11-04 18:32


oorsprong


antwoorden:


Ik vind het geen bijzonder goede oefening om iets te doen als:

myObj.getMyList().add(x);

aangezien je een privéklasvariabele op een niet-leesbare manier blootgeeft, maar dat gezegd zijnde, ik zie het vrij vaak (ik kijk naar jou, automatisch gegenereerde klassen). Ik zou zeggen dat in plaats van het op die manier te doen, een niet-wijzigbare lijst retourneert en gebruikers van de klasse toe staat om via een expliciete methode aan de lijst toe te voegen:

public class MyClass{
    private final List<String> myList = new ArrayList<String>();

    public List<String> getList(){
        return Collections.unmodifiableList(this.myList);
    }

    public void addToList(final String s){
        this.myList.add(s);
    }
}

BEWERK Na het bekijken van uw opmerkingen, wilde ik iets toevoegen over uw setteridee:

Ik bedoelde het gebruik van die regel code in een nieuw soort van setter in de klasse zelf, zoals openbare nietige setter (someElement) {this.myLinkedList.add (someElement);}

Als ik u goed begrijp, zegt u dat u een methode wilt blootleggen die alleen wordt toegevoegd aan uw lijst. Over het geheel genomen is dit waar ik denk dat je zou moeten schieten, en wat velen hebben geschetst in de antwoorden, echter, het labelen als een setter is een beetje misleidend omdat je niets anders toewijst (instelt). Dat, en ik adviseer sterk om, indien mogelijk, een read-only lijst van uw gettersysteem terug te sturen.


14
2017-11-04 18:44



Over het algemeen mag je niet aannemen dat de lijst die wordt teruggestuurd door de getter de originele is. Het kan bijvoorbeeld worden ingericht of geproxied. Als u wilt voorkomen dat een nieuwe lijst wordt ingesteld op het doelobject, kunt u in plaats daarvan een invoermethode definiëren voor de doelklasse.


8
2017-11-04 18:40



Ik zou willen voorstellen dat het in dit geval het beste is om uw Encapsulation-principes te volgen en een methode te gebruiken om elementen aan de lijst toe te voegen. U hebt de toegang tot uw lijst beperkt door deze te maken private zodat andere klassen geen directe toegang hebben tot het datatype.

Laat de klas die je opslaat ArrayList directe toegang tot de lijst hebben, maar wanneer andere klassen aan de lijst willen toevoegen, gebruik dan een add() methode.


8
2017-11-04 18:42



Zodra je een hebt Collection van welke aard dan ook, het is over het algemeen geen slecht idee om methoden toe te voegen zoals add(), remove() naar de interface van uw klas als het logisch is dat clients objecten uit uw privélijst kunnen toevoegen of verwijderen.

De reden waarom het nuttig is om deze extra methoden geïmplementeerd te hebben (het lijkt misschien overdreven, omdat na al die methoden meestal gewoon de methode op de Collection) is dat u kwaadwillende klanten beschermt om dingen naar uw lijst te doen die u niet wilt dat ze doen, omdat de interface van de meesten dat is Collections bevatten meer dan alleen de add()en remove() methoden en meestal, je wilt niet dat klanten rommelen met dingen die je niet kunt controleren. Daarom is het inkapselingprincipe zo belangrijk voor je leraar.

Nog een pluspunt: als u op enig moment zou beslissen dat aan een bepaalde voorwaarde moet worden voldaan wanneer een object aan uw lijst wordt toegevoegd, kan dit eenvoudig worden geïmplementeerd in de methode die u al heeft. Als je een klant toegang geeft tot de directe referentie van je lijst, is het helemaal niet eenvoudig om dit soort dingen te implementeren (wat niet zeldzaam is).

Ik hoop dat dit helpt


4
2017-11-04 18:44



Het hangt van de toepassing af - beide zijn acceptabel. Kijk goed naar de klas die je aan het schrijven bent en beslis of je wilt dat gebruikers direct toegang hebben tot de inhoud van de lijst, of dat je eerst de voorkeur geeft aan een tussentijds proces.

Stel dat u een klas hebt ListEncrypter welke jouw houdt MyLinkedList lijst. Het doel van deze klasse is om alles te versleutelen dat is opgeslagen MyLinkedList. In dit geval wilt u een aangepaste toevoegingsmethode opgeven om het toegevoegde item te verwerken voordat u het in de lijst plaatst. Als u het element wilt openen, moet u het ook verwerken:

public void add(Object element)
{
    MyLinkedList.add(encrypt(element););
}

public Object get(int index)
{
    return decrypt(MyLinkedList.get(index););
}

In dit geval wilt u duidelijk de toegang van de gebruiker tot de MyLinkedList variabele, omdat de inhoud wordt gecodeerd en ze er niets mee kunnen doen.

Aan de andere kant, als u niet echt bezig bent met het verwerken van de gegevens (en je bent er zeker van dat je dat in de toekomst nooit meer hoeft te doen), kunt u het maken van de gespecialiseerde methoden overslaan en de gebruiker rechtstreeks toegang geven tot de lijst via de get methode.


2
2017-11-04 18:49



Als ik je vraag goed begrijp, heb je een klasse met een List (het zou waarschijnlijk moeten zijn final, maar u vermeldt dat niet) en u wilt bellers toestaan ​​om toe te voegen aan de List, maar niet in staat om het te vervangen.

U kunt een getter voor de lijst opgeven:

public List<E> getMyList() {
  return myList;
}

Of geef een methode om aan die lijst toe te voegen:

public void addToMyList(E e) {
  myList.add(e);
}

Beide zijn geldige ontwerpbeslissingen, maar die u gebruikt, is afhankelijk van uw gebruik. De eerste optie geeft bellers directe toegang tot de List, effectief openbaar maken. Dit is handig wanneer gebruikers de lijst herhaaldelijk aanpassen en met de lijst gaan werken, maar het kan problematisch zijn omdat u het. Niet meer kunt vertrouwen List is in een of andere betrouwbare staat (de beller kan het legen, herordenen of zelfs met kwaadwilligheid objecten van een ander type invoegen). Dus de eerste optie moet alleen worden gebruikt als u de beller wilt vertrouwen.

De tweede optie geeft de beller minder macht, omdat ze dat kunnen enkel en alleen voeg één element tegelijkertijd toe. Als u aanvullende functies wilt bieden (invoegen, alles toevoegen, enz.), Moet u elke bewerking om de beurt inpakken. Maar het geeft je meer zelfvertrouwen, omdat je er zeker van kunt zijn List wordt alleen aangepast op manieren die u goedkeurt. Met deze laatste optie verbergt (encapsulates) ook het implementatiedetail dat u gebruikt a List helemaal, dus als encapsulatie belangrijk is voor uw gebruik, wilt u deze kant opgaan om te voorkomen dat uw interne datastructuren worden blootgesteld en stelt u alleen de gedrag u wilt aan bellers verlenen.


2
2017-11-04 18:45