2

I was reading this article on why getter and setters are evil. The article doesn't say not to use them ever, but, it's telling you to think in a way that limits the use of those methods, or to quote the article:

Don't ask for the information you need to do the work; ask the object that has the information to do the work for you.

what happens when you need to display data in a GUI, but don't have getter methods? The article covers this briefly, but not fully. It mentions passing a JComponent to the class, but if you're GUI changes, it could lead to a lot of work to fix.

Take for example, you have a Book class (making this example limited to keep it readable).

public final class Book {

    private String title;
    //Authors is class with the attributes authorFirstname, authorLastname
    private List<Author> listofAuthors;


    public Book(String title, List<Author> listofAuthors)
    {
        //initialization
    }

    //other methods that do work
}

If I have a GUI that has a JTextField to display the book title and a JTable to display the list of authors, how would I write my method to "do the work" for me and display the result? Is this one of those times where a getter is necessary?

4 Answers4

1

Think of it this way: Getters (public functions) are a bridge for private attributes.

I'll write you a simple example to modify your TextField using OOP.

Book class:

public final class Book {
private String title;
//Authors is class with the attributes authorFirstname, authorLastname
private List<Author> listofAuthors;


public Book(String title, List<Author> listofAuthors)
{
    //initialization
}
public String getTitle() {
return this.title; }
}

GUI:

author1 = new Author("jhon");
author 2 = new Author("alsojhon");
list = new ArrayList();
list.add(author1);
list.add(author2)
b = new Book("stack",list);
JTextField field;
field.setText(b.getTitle());
Oussama Ben Ghorbel
  • 2,132
  • 4
  • 17
  • 34
1

You can create three kind of classes:

  1. Entity, classes that represents a business concept and have only one unique id, like Client class with Id the username. It is usually a mutable class. You should have all the business logic here. You should not open his data with getters and setters.

  2. Value object, classes that represents a business concept but not have an unique id, like Email class. It is usually an imm.utable class. You should have all the business logic here.

  3. Data structure (kind of DTO), classes to save data only, without behavior, maybe you have setters and getters to access those datas.

What can I do if I need to access all Client data if I do not have accesors? Well, you should transform Client to a DTO. You can use a framework like Orika. Or you can create a method into Client class to ask for information (mediator pattern).

I like second option but it implies more work:

class Client{
    private String name;
    ...
   public void publishInfo(ClientInfo c){
      c.setName(name);
      ...
    }
}

class ClientInfo{
    private String name;
    //GETTERS
    //SETTERS
}
1

Allen Holub's article (the one you mentioned) is completely right, you shouldn't ask for data, at least when you're doing Object-Orientation. And no, displaying things is not a valid excuse to open up an object.

If you have a Book, just ask for the Book to display itself! It shouldn't matter whether that uses a JTextField or JTable or whatever. Depending on your requirements of course, you could do:

public final class Book {
    ...
    JComponent display() {
        ...
    }
}

The point of Object-Orientation is of course, that you are trying to localize changes (restrict to one class as much as possible). The only way to do that is to localize the functionality that depends on the same things into (preferably) the same class. Also called increasing "cohesion".

So now, if the Book internals change, all of the things, including how the Book is displayed is in the Book itself, so there is no need to "hunt" for code that uses the Book.

Now, for the answer that this is not "clean", because you are mixing presentation code with "business logic". It may be interesting to note, that the whole idea of not mixing presentation with "business logic" comes from earlier times, when we still thought that presentation might be "remote" to the "business objects", where "business objects" might be used by multiple applications for different things. Ie. multi-tier designs. YAGNI. Most of the time there is no real reason to have artificial technical boundaries inside a single application. There is no harm done if the Book knows it's part of a GUI application, and there are real benefits (maintainability) to have.

Edit: this is how the `display() method could look like in detail, with displaying the title and authors (pseudocode for Swing):

public final class Book {
    private final String title;
    private final List<Author> authors;
    ...
    public JComponent display() {
        JPanel bookPanel = new JPanel();
        bookPanel.add(new JLabel(title));
        JList authorsList = new JList(); // Or similar
        for (Author author: authors) {
            authorsList.add(author.display());
        }
        bookPanel.add(authorsList);
        return bookPanel;
    }
}

And then you can simply add() that component to whatever swing container you want to display the book in.

Robert Bräutigam
  • 7,514
  • 1
  • 20
  • 38
  • Let's say I have a JTable to display authors, just for learning purposes, can you complete the code by showing how I would display the list of author if don't have a getter? –  May 01 '17 at 14:23
  • You shouldn't "have" a `JTable` to display authors. You should ask the Book to display its authors for you. For example: `JComponent displayAuthors()` – Robert Bräutigam May 01 '17 at 14:39
  • Bare with me, I don't fully understand. How would I ask it to display the authors for me? This is why I asked if you could complete your example code. –  May 01 '17 at 14:40
  • See edit. I assumed that the `Author` object will also know how to display itself. – Robert Bräutigam May 01 '17 at 14:56
  • Wonderful. Many thanks for you example and explanation. With this example, I can figure out the Author object on my own. –  May 01 '17 at 14:57
  • Where would the event handler go if I wanted to change something? For example, If I wanted to remove an author, I need to know what index the author is at in the JList, so I can remove it, and create a new Book object(the class is immutable). –  May 01 '17 at 16:21
  • Well, you can make it mutable, if you want it to be. If you want to be able to change the Book, I would perhaps just make it mutable, and define the `JComponent` in a way that changes the `Book` instance. – Robert Bräutigam May 01 '17 at 16:29
0

Are you asking about a method to display all the information for you? I'm not following.

If that is what you're asking, here's my recommendation: Don't write it in the class with the window code in it. It won't be very clean. Make a new class with that method in it (Yes, getters are necessary, they make OOP easier, but that's biased).

What I do if I want to iterate through a list is make a StringBuilder, along with a for loop, that adds the name of the author. Then, have the method return the list of authors.

List<Authors> a;
StringBuilder d = new StringBuilder();
for (int i = 0; i < a.size(); i++) {
    d.append(a.get(i).getName() + ", ");
}
return d.toString();
//It's just sudo code, but still.
FlashDaggerX
  • 89
  • 10
  • I'm trying to accomplish what the article is saying to do, let the class do the work for you. It saying that while you can use getters, it best to avoid them. –  Apr 30 '17 at 15:49
  • Getters and Setters make the structure of an object neater. But I guess everyone has their own programming style. – FlashDaggerX Apr 30 '17 at 17:38