Разработка OO Spring REST API - преобразование или наследование форм - PullRequest
1 голос
/ 19 апреля 2019

У меня следующий сценарий (упрощенный) в Spring REST API.

public class FooService 
{
    public void createFoo(FooData data) { ... }
}
public class FooController
{
    public void makeFooAnymous(AnymousFooForm aif) { ... }
    public void makeFooUser(UserFooForm uif) { ... }
}

Обе конечные точки makeIssueAnymous и makeIssueUser хотят вызвать createIssue, потому что они делают то же самое, но имеют некоторые различия в API.

Раствор I

В контроллере обе конечные точки вызывают метод

private <T> void createFooUsing(T fooForm, Function<T, FooData> formToDataConverter)
{
    // doSomeCommonConversionLogic
    try
    {
        createSomeResource();
        fooService.saveFoo(formToDataConverter.apply(fooForm), andMaybeAnotherParam);
    } catch (SomeExcp e) { doSomeThingSpecial() }
}

И классы форм выглядят так:

class UserFooForm
{
     public String someData;
     public FooData toFooData(String otherField) { ... } 
}
class AnymousFooForm
{
     public String someDatas;
     public String otherField;
     public FooData toFooData(int paramFromPath) { ... } 
}

А код в методе cotroller выглядит так:

public void makeFooUser(@RequestBody UserFooForm fooForm)
{
    return createFooUsing(fooForm, f -> f.toFooData("abc"));
}
public void makeFooAnymous(@RequestBody UserFooForm fooForm)
{
    return createFooUsing(fooForm, f -> f.toFooData(123));
}

Решение II:

Превратить FooData в интерфейс

interface FooData {
    String getSomeData();
    String getOtherField();
}

И заставьте UserIssueForm и AnymousIssueForm реализовать интерфейс, скопируйте «doSomeCommonConversionLogic» и просто передайте его методу сервиса createIssue.

public void makeFooUser(@RequestBody UserFooForm fooForm)
{
    // doSomeCommonConversionLogic
    try
    {
        createSomeResource();
        fooForm.prepare("abc");
        fooService.saveFoo(fooForm, andMaybeAnotherParam);
    } catch (SomeExcp e) { doSomeThingSpecial() }
}
public void makeFooAnymous(@RequestBody AnymousFooForm fooForm)
{
    // doSomeCommonConversionLogic
    try
    {
        createSomeResource();
        fooForm.prepare(123);
        fooService.saveFoo(fooForm, andMaybeAnotherParam);
    } catch (SomeExc e) { doSomeThingSpecial() }
}

Было бы замечательно, если бы не было такого общего кода. Это связано с HTTP, и я не хочу иметь его в службе.

Что лучше? А может что-то еще?

...