Как использовать аннотацию Lombok @Builder для методов

Мне нужен простой способ построения тестовых данных, и я обнаружил, что шаблон Builder хорошо подходит, как описано здесь. Однако, чтобы еще больше сократить стандартные коды в тестах компонентов, я нашел @Builder из Project Lombok. быть хорошим кандидатом, чтобы попробовать. Однако я не могу найти документацию или онлайн-примеры того, как использовать его в методе. Я хочу использовать @Builder в каком-то фабричном методе, так как я не могу внести какие-либо изменения в реализацию.

Может ли кто-нибудь привести пример того, как на самом деле использовать @Builder в методе?


person user3139545    schedule 28.04.2016    source источник
comment
почему вы хотите использовать методы? см. пример использования в классе.   -  person Deendayal Garg    schedule 28.04.2016
comment
потому что у меня нет доступа к классу и я не могу вносить в него какие-либо изменения.   -  person user3139545    schedule 28.04.2016


Ответы (2)


Использование метода @Builder on для создания экземпляров Dog и Cat.

В этом примере @Value создает окончательный неизменяемый объект значения с помощью методов доступа (геттеров), конструктора всех аргументов, equals(), hashCode() и toString().

import static org.junit.Assert.*;
import lombok.Builder;
import lombok.Value;

import org.junit.Test;

@SuppressWarnings("javadoc")
public class ImmutableAnimals {

    @Builder(builderMethodName = "dogBuilder")
    public static Dog newDog(String color, String barkSound) {
        return new Dog(color, barkSound);
    }

    @Builder(builderMethodName = "catBuilder")
    public static Cat newCat(String color, String meowSound) {
        return new Cat(color, meowSound);
    }

    public static interface Animal {
        String getColor();
    }

    @Value
    public static class Cat implements Animal {
        String color;
        String meowSound;
    }

    @Value
    public static class Dog implements Animal {
        String color;
        String barkSound;
    }

    @Test
    public void testDog() {
        final String expectedBarkSound = "woof";
        final String expectedColor = "brown";

        final Dog dog = ImmutableAnimals.dogBuilder()
            .barkSound(expectedBarkSound)
            .color(expectedColor)
            .build();

        assertEquals(expectedBarkSound, dog.getBarkSound());
        assertEquals(expectedColor, dog.getColor());
    }

    @Test
    public void testCat() {
        final String expectedMeowSound = "purr";
        final String expectedColor = "white";

        final Cat cat = ImmutableAnimals.catBuilder()
            .meowSound(expectedMeowSound)
            .color(expectedColor)
            .build();

        assertEquals(expectedMeowSound, cat.getMeowSound());
        assertEquals(expectedColor, cat.getColor());
    }
}

Вот еще один пример с теми же классами предметной области, но с изменяемыми значениями. Однако, как всегда, отдавайте предпочтение неизменности, когда это возможно.

import static org.junit.Assert.*;
import lombok.Builder;
import lombok.Data;

import org.junit.Test;

@SuppressWarnings("javadoc")
public class MutableAnimals {

    @Builder(builderMethodName = "dogBuilder")
    public static Dog newDog(String color, String barkSound) {
        final Dog dog = new Dog();
        dog.setBarkSound(barkSound);
        dog.setColor(color);
        return dog;
    }

    @Builder(builderMethodName = "catBuilder")
    public static Cat newCat(String color, String meowSound) {
        final Cat cat = new Cat();
        cat.setMeowSound(meowSound);
        cat.setColor(color);
        return cat;
    }

    public static interface Animal {
        String getColor();
    }

    @Data
    public static class Cat implements Animal {
        String color;
        String meowSound;
    }

    @Data
    public static class Dog implements Animal {
        String color;
        String barkSound;
    }

    @Test
    public void testDog() {
        final String expectedBarkSound = "woof";
        final String expectedColor = "brown";

        final Dog dog = MutableAnimals.dogBuilder()
            .barkSound(expectedBarkSound)
            .color(expectedColor)
            .build();

        assertEquals(expectedBarkSound, dog.getBarkSound());
        assertEquals(expectedColor, dog.getColor());
    }

    @Test
    public void testCat() {
        final String expectedMeowSound = "purr";
        final String expectedColor = "white";

        final Cat cat = MutableAnimals.catBuilder()
            .meowSound(expectedMeowSound)
            .color(expectedColor)
            .build();

        assertEquals(expectedMeowSound, cat.getMeowSound());
        assertEquals(expectedColor, cat.getColor());
    }
}
person Jeff    schedule 28.04.2016
comment
Не могли бы вы объяснить, зачем нужен @Value? - person user3139545; 28.04.2016
comment
@Value создает окончательный объект неизменяемого значения с помощью методов доступа (геттеров), конструктора всех аргументов, equals(), hashCode() и toString(). Я просто сделал это для удобства в примере. - person Jeff; 28.04.2016
comment
Могу ли я использовать @Builder в изменяемых классах с сеттерами? - person user3139545; 28.04.2016
comment
Однако добавлен изменяемый пример, всегда предпочитающий неизменность, когда это возможно, - person Jeff; 28.04.2016

Вот как вы используете @Builder.

//Employee.Java
import lombok.Builder;
import lombok.ToString;

@Builder
@ToString
public class Employee {
   private final String empName;
   private final int salary;
}

//   Main.java

public class Main {

public static void main(String[] args) {
    Employee emp = Employee.builder().empName("Deendaya").salary(100).build();
    System.out.println(emp);
  }
}
person Deendayal Garg    schedule 28.04.2016
comment
Довольно аккуратное объяснение. - person whitehat; 21.11.2017
comment
Это не отвечает на вопрос: может ли кто-нибудь привести пример того, как на самом деле использовать @Builder в методе? - person Jeff; 08.12.2017
comment
Это правильный ответ, и здесь вам говорят наглядный пример: Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build(); можно использовать, если вы добавите @ Аннотация построителя к классу Person. - person russellhoff; 09.01.2018
comment
@russellhoff На самом деле это не так. Вопрос был конкретно об использовании @Builder в методе, а не на уровне класса. В документация по ломбоку есть краткий пример только для уровня класса, и из описания непросто понять, как использовать его на уровне метода. - person Jens Hoffmann; 09.01.2018
comment
@JensHoffmann, вы правы, ОП хотел знать его использование на уровне методов, а официальная документация, которая на самом деле довольно беспорядочна, не объясняет это четко. - person russellhoff; 10.01.2018
comment
Это объясняется чище, проще и подробнее по этой ссылке baeldung.com/lombok-builder- custom-setter и baeldung.com/lombok-builder - person fgul; 26.01.2019