The best design template to support static functions of common classes that implement the interface

I have an interface Operations:

public interface Operations{

    Operations add(Operations op);

    Operations subtract(Operations op);
}

This interface should allow the user to choose how to perform simple calculations. For example, if the user just wants to use the data type Integerand its basic operations, he can use the class MyInteger:

// simple implementation without type check etc..
public final class MyInteger implements Operations{
    private final int delegate;

    public MyInteger(int i){
        delegate = i;
    }

    @Override
    Operations add(Operations other){
        return new MyInteger(delegate + ((MyInteger) other).delegate);
    }
    @Override
    Operations subtract(Operations other){
        return new MyInteger(delegate - ((MyInteger) other).delegate);
    }
    (...)
}

In other classes, calculations based on interface functions will be performed Operations. But sometimes I need a static context, for example valueOf(val), which returns the implementation of the corresponding class for a given String, double, int, etc., As in this example:

public class Calculation<D extends Operations> {

    private final D value1, value2;
    private final D value3 = D.valueOf(4);  // cannot implement this in interface 

    public Calculation(D value1, D value2){
        this.value1 =value1;
        this.value2 = value2;
    }

    public D sumPlusValue3(){
        return value1.plus(value2).plus(value3);
    }
}

So,

Calculation<MyInteger> calc = new Calculation<MyInteger>(new MyInteger(1), new MyInteger(2));
Operations result = calc.sumPlusValue3();

, , , Builder Factory, , ,

Operations integerImpl = OperationsBuilder.create("Integer");

D value3 Calculation.

1:

@Stefan Haustein, . @davidxxx - a valueOf(int val) .

+4
2

Calculation D , valueOf Operations, .

"dummy" valueOf , Class<D> Calculations. newInstance(), , , , addInt, . , .

- abstractOf abstract Calculation, , Calculation:

Calculation<MyInteger> calc = new Calculation<MyInteger>(
    new MyInteger(1), new MyInteger(2)) {
      public MyInteger valueOf(int i) {
        return new MyInteger(i);
      }
    });

Operations result = calc.sumPlusValue3();

, , -, "" " /". , - .

P.S. factory, Operations :

public final class MyInteger implements Operations{
  private final int delegate;

  public static final OperationsFactory<MyInteger> FACTORY = 
    new OperationsFactory<>() {
      @Override
      MyInteger valueOf(int i) {
        return new MyInteger(i);
      }
    };

  public MyInteger(int i){
      delegate = i;
  }

  @Override
  Operations add(Operations other){
      return new MyInteger(delegate + ((MyInteger) other).delegate);
  }
  @Override
  Operations subtract(Operations other){
    return new MyInteger(delegate - ((MyInteger) other).delegate);
  }
  (...)
}

...

+1

1) : factory

:

private final D value3 = D.valueOf(4);  // cannot implement this in interface 

value3 , factory.
valueOf() ( ) .

factory Calculation, value3.

, :

private final D value3 = D.valueOf(4);

public Calculation(D value1, D value2){
    this.value1 =value1;
    this.value2 = value2;
}

:

private final D value3; 

public Calculation(D value1, D value2, FactoryD factoryD){
    this.value1 =value1;
    this.value2 = value2;
    this.value3 = factoryD.create(4);
}

Function factory:

private final D value3; 

public Calculation(D value1, D value2, IntFunction<D> factoryD){
    this.value1 =value1;
    this.value2 = value2;
    this.value3 = factoryD.apply(4);
}

:

Calculation<MyInteger> calc = new Calculation<>(new MyInteger(1), new MyInteger(2), MyInteger::new );
Operations result = calc.sumPlusValue3();

Operations -.

2) Operations .

, Operations , :

public interface Operations{

    Operations add(Operations op);

    Operations subtract(Operations op);
}

:

public interface Operations<T> {

    Operations<T> add(Operations<T> op);

    Operations<T> subtract(Operations<T> op);

    T getValue();

}

MyInteger :

public final class MyInteger implements Operations<Integer> {

    private final int delegate;

    public MyInteger(int i) {
      delegate = i;
    }

    @Override
    public Operations<Integer> add(Operations<Integer> other) {
      return new MyInteger(delegate + other.getValue());
    }

    @Override
    public Operations<Integer> subtract(Operations<Integer> other) {
      return new MyInteger(delegate - other.getValue());
    }

    @Override
    public Integer getValue() {
      return delegate;
    }
}

Calculation : Operations Operations :

public class Calculation<C, D extends Operations<C>> {

    private final D value1, value2;
    private final D value3; 

    public Calculation(D value1, D value2, IntFunction<D> factoryD){
        this.value1 =value1;
        this.value2 = value2;
        this.value3 = factoryD.apply(4);
    }

    public Operations<C> sumPlusValue3(){
        return value1.add(value2).add(value3);
    }        
}

:

Calculation<Integer, MyInteger> calc = new Calculation<>(new MyInteger(1), new MyInteger(2), MyInteger::new );
Operations<Integer> result = calc.sumPlusValue3();
System.out.println(result.getValue());

:

7

+2

Source: https://habr.com/ru/post/1689524/


All Articles