Objaśnienie kodu, nieznany sposób dodawania obiektów do listy.

0

Sory za dziwną nazwę tematu ale nie mogłem nic lepszego wymyślić.

Proszę o wyjaśnienie jednego kodu:


List<Task> tasks = new ArrayList<Task>();

public void addTask(Date startDate, int duration, String title, String description) 
{ 
tasks.add(new Task.Builder()
   .withTitle(title).withDescription(description)
   .withDate(startDate)
   .withDuration(duration) 
   .build()); }

Metoda addTask ma dodawać nowe zadania do listy zadań, ale nie rozumiem w jaki sposób jest to dodawanie... jest task.add(new Task.Builder()) czyli to oznacza że w klasie Task znajduje się metoda statyczna Builder, która ma utworzyć zadanie tak? I na jakiej zasadzie to działa że po Builder() jest znów operator , . ' i kolejna metoda withTiltle() i tak dalej.

1

Chodzi o wewnętrzą klasę statyczną. Klasa ta ma metody które opakowywują obiekt klasy Task w dodatkowe właściwości i zwracają opakowany obiekt klasy Task, dlatego możliwe jest kolejne wywoływanie metod.
Na podobnej zasadzie działają klasy LocalDate i LocalTime z biblioteki JodaTime. Przykładowy kod klasy Task poniżej:

public class Task {
    public static TaskBuilder Builder() {
        return new TaskBuilder();
    }

    private long id;

    private String subject;

    private Date startDate;

    private Date closeDate;

    public PropertiesMapBuilder toMapWith() {
        return new PropertiesMapBuilder(this);
    }

    public String getSubject() {
        return subject;
    }

    public Date getStartDate() {
        return startDate;
    }

    public Date getCloseDate() {
        return closeDate;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Task{");
        sb.append("id=").append(id);
        sb.append(", subject='").append(subject).append('\'');
        sb.append(", startDate=").append(startDate);
        sb.append(", closeDate=").append(closeDate);
        sb.append('}');
        return sb.toString();
    }

    public static class PropertiesMapBuilder {
        private Map<String, Object> propertiesMap =
                new HashMap<String, Object>();
        private Task task;

        private PropertiesMapBuilder(Task task) {
            this.task = task;
        }

        public PropertiesMapBuilder subject() {
            propertiesMap.put("subject", task.getSubject());
            return this;
        }

        public PropertiesMapBuilder startDate() {
            propertiesMap.put("start_date",
                    new java.sql.Date(task.getStartDate().getTime()));
            return this;
        }

        public PropertiesMapBuilder closeDate() {
            propertiesMap.put("close_date",
                    new java.sql.Date(task.getCloseDate().getTime()));
            return this;
        }

        public Map<String, Object> build() {
            return propertiesMap;
        }

    }

    public static class TaskBuilder {
        private Task task;

        private TaskBuilder() {
            task = new Task();
        }

        public TaskBuilder withId(long id) {
            task.id = id;
            return this;
        }

        public TaskBuilder withSubject(String subject){
            task.subject = subject;
            return this;
        }

        public TaskBuilder withStartDate(Date startDate){
            task.startDate = startDate;
            return this;
        }

        public TaskBuilder withCloseDate(Date closeDate){
            task.closeDate = closeDate;
            return this;
        }

        public Task build() {
            return task;
        }
    }
}
0

Dzięki teraz już to rozumiem. Wyjaśnij mi jeszcze jedną rzecz. Widzę że ta wewnętrzna klasa Builder ma utoworzyć wartości dla pól klasy Task, a to nie łatwiej i prościej by było to zrobić w konstruktorze klasy Task?

0

Ach tak... wzorzec projektowy. Dzięki teraz wszystko kumam.

1

@dejmien w wielkim skrócie, czemu builder a nie konstruktor. Wyobraź sobie że możesz utworzyć dany obiekt podając dowolny podzbiór parametrów, załóżmy że parametrów jest 10. To znaczy że mozesz utworzyć obiekt podając dowolne z tych 10 parametrów. Policz teraz ile rożnych konstruktorów potrzebowałbyś żeby to zrealizować.
Co więcej, zastanów sie jak mógłbyś to zrobić, gdyby każdy z tych parametrów był tego samego typu... ;]

1 użytkowników online, w tym zalogowanych: 0, gości: 1