dimanche 6 octobre 2019

Encapsulate Java Reflection (Custom Annotation) from Caller

  1. I need to simplify the @Sequence annotation usage where caller don't need to manually AnnotationParser.getValue(sampleCaller)
  2. Ideally caller just mark @Sequence(strategy = Strategy.STRATEGY_A), then the value will be auto injected to the field.
  3. My overall design pattern looks messy, please recommend a better design pattern.

This is the sample output "200100-6102019"

SampleCaller.java

package com.common.sequence;

public class SampleCaller {

    @Sequence(strategy = Strategy.STRATEGY_A)
    private String sequenceA;

    public static void main(String args[]) {
        SampleCaller sampleCaller = new SampleCaller();
        System.out.println(AnnotationParser.getValue(sampleCaller)); //TODO Need Changes
    }
}

Sequence.java

package com.common.sequence;

import java.lang.annotation.*;

@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Sequence {
    Strategy strategy();
}

AnnotationParser.java

package com.common.sequence;

import java.lang.reflect.Field;

public class AnnotationParser {

    public static String getValue(SampleCaller ob)  {
        for (Field field : ob.getClass().getDeclaredFields()) {
            if (field.isAnnotationPresent(Sequence.class)) {
                Sequence sequence = field.getAnnotation(Sequence.class);
                switch (sequence.strategy()) {
                    case STRATEGY_A: {
                        StrategyA strategyA = new StrategyA(100L);
                        return strategyA.value();
                    }
                    case STRATEGY_B: {
                        StrategyB strategyB = new StrategyB(100L);
                        return strategyB.value();
                    }
                    default: return null;
                }
            }
        }
        return null;
    }
}

Strategy.java

package com.common.sequence;

public enum Strategy {
    STRATEGY_A,
    STRATEGY_B;
}

AbstractStrategy.java

package com.common.sequence;

public abstract class AbstractStrategy {
    private Long startFrom;

    public AbstractStrategy(Long startFrom) {
        this.startFrom = startFrom;
    }

    protected abstract Long sequence();
    protected abstract Long prefix();
    public String value(){
        long sequence = sequence() + startFrom;
        return sequence +"-"+ prefix();
    }
}

StrategyA.java

package com.common.sequence;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class StrategyA extends AbstractStrategy{
    public StrategyA(Long startFrom) {
        super(startFrom);
    }

    @Override
    protected Long sequence() {
        return 100000L;
    }

    @Override
    protected Long prefix() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyyy");
        return Long.valueOf(LocalDateTime.now().format(formatter));    }
}

StrategyB.java

package com.common.sequence;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class StrategyB extends AbstractStrategy {
    public StrategyB(Long startFrom) {
        super(startFrom);
    }

    @Override
    protected Long sequence() {
        return 200000L;
    }

    @Override
    protected Long prefix() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyyy");
        return Long.valueOf(LocalDateTime.now().format(formatter));
    }
}

Aucun commentaire:

Enregistrer un commentaire