Simple code implementation for universal pricing

What scenarios should use generic pricing

If the cost attributes of a commodity are constantly changing, such as new fees that come in every other direction (new fees calculated according to the new rules), as a developer you will need to nervously maintain your existing pricing interface each time, testing will also take a lot of time to verify the impact on other costs.Based on this point, I think that if the initial pricing is made into a common pricing interface, I only need to pay attention to the new fee calculation rules for each additional fee, without modifying the existing fee calculation rules, I can avoid some BUG s.

Simple code implementation

The general idea is to use Spring's container management to load all pricing types into the pricing execution class at project startup, and inject the specific invocation method just as you would normally write code.This method is not used in actual projects.

1. General Pricing Interface

import java.math.BigDecimal;
import java.util.Map;

public interface CommonValuation {

    /**
     * Pricing Type
     * @return
     */
    String getValuationType();

    /**
     * Pricing interface, subclasses implement their own pricing methods
     * @param paramsJson
     * @param result  Save all fee types and amounts
     * @return
     */
    void valuation(String paramsJson, Map<String, BigDecimal> result);

}

Description: The pricing interface is defined here. Specific types of pricing and calculation rules are implemented by subclasses, which are managed by Spring.

2. Execution Class of Pricing Interface

@Component
public class CommonValuationChain {

    @Autowired
    private ApplicationContext applicationContext;

    private List<CommonValuation> commonValuationList = new ArrayList<>();

    /**
     * Load all cost calculation classes in the project
     */
    @PostConstruct
    private void init() {

        String[]  commonValuationArr = applicationContext.getBeanNamesForType(CommonValuation.class);

        for (String cvName : commonValuationArr) {

            commonValuationList.add(applicationContext.getBean(cvName, CommonValuation.class));
        }

        // Pricing order can be determined by @Order
        AnnotationAwareOrderComparator.sort(commonValuationList);

    }

    public Map<String,BigDecimal> valuation(String paramsJson) {
        // Save all expenses and corresponding amounts
        Map<String,BigDecimal> result = new HashMap<>();

        for(CommonValuation valuation : commonValuationList) {
           valuation.valuation(paramsJson, result);
        }

        return result;
    }
}

Description: With the help of Spring's @PostConstruct annotation, all the cost type calculation classes are loaded into the commonValuationList for business use, and the subclasses can also resolve the order of calculation according to the @Order annotation.

3. Specific cost types

@Component
@Order(4)
public class DiscountMoneyValuation implements CommonValuation{


    /**
     * Less Free
     * @return
     */
    @Override
    public String getValuationType() {
        return "discountMoney";
    }

    @Override
    public void valuation(String paramsJson, Map<String, BigDecimal> result) {
        // Pseudo code, where paramsJson can be converted to the desired pricing parameters to calculate the true price
        BigDecimal discountMoney = new BigDecimal("-10.6");


        result.put(getValuationType(), discountMoney);
    }
}



@Component
@Order(333)
public class TestMoneyValuation implements CommonValuation{

    @Override
    public String getValuationType() {
        return "testMoney";
    }

    @Override
    public void valuation(String paramsJson, Map<String, BigDecimal> result) {
        // Pseudo code, where paramsJson can be converted to the desired pricing parameters to calculate the true price
        BigDecimal testMoney = new BigDecimal("100");

        result.put(getValuationType(), testMoney);
    }
}

4. Call Class

	@Autowired
	private CommonValuationChain commonValuationCore;

	@Test
	public void valuationTest() {
        Map<String,BigDecimal> result = commonValuationCore.valuation(null);

		for(Map.Entry<String,BigDecimal> price : result.entrySet()) {
            System.out.println(price.getKey() + "´╝îAmount of money" + price.getValue());
        }
	}

5. Execution results

summary

Above is my own realization of universal pricing. I have limited level, I can not think of a more scalable and usable method for the time being. If you have a better method, you can comment below. At the same time, you are welcome to give guidance and criticism.

Tags: Java Spring less

Posted on Tue, 24 Mar 2020 09:26:07 -0700 by reversenorm