摘要:本人郵箱歡迎轉(zhuǎn)載轉(zhuǎn)載請注明網(wǎng)址代碼已經(jīng)全部托管有需要的同學自行下載引言在工作項目中遇到以下一個問題公司有一款產(chǎn)品遇到給不同代理商代理售賣但是不同的代理商分潤的方式各自不同有以下幾個中分潤方式每筆固定收益元,則填寫代理商收益每筆收益率為則填寫
引言本人郵箱:
歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明網(wǎng)址 http://blog.csdn.net/tianshi_kco
github: https://github.com/kco1989/kco
代碼已經(jīng)全部托管github有需要的同學自行下載
在工作項目中遇到以下一個問題.
公司有一款產(chǎn)品,遇到給不同代理商代理售賣.但是不同的代理商分潤的方式各自不同.有以下幾個中分潤方式.
每筆固定收益1元,則填寫代理商收益1.00
每筆收益率為0.1%則填寫代理商收益0.1%
每筆收益率為0.1%加上固定收益1元,則填寫代理商收益0.1%+1.00
每筆收益率為0.1%,封頂3元,保底1元則填寫代理商收益1.00~0.1%~3.00
梯度分潤 例如 0.1%<10000<0.2%<20000<0.3%<30000<0.5%
少于10000 按照 0.1% 分潤
少于20000 按照 0.2% 分潤
少于30000 按照 0.3% 分潤
多于30000 按照 0.5% 分潤
然而發(fā)現(xiàn)公司的項目代碼中竟然是硬編碼的.強硬的解析是否,把所有規(guī)則需要使用的參數(shù)信息都集中在一個類中,不利于維護.
多說無益,讓各位感受一下項目中的代碼吧.
public class AgentShareRule { private Integer profitType; // 分潤類型 private BigDecimal perFixIncome; //第一,四種情況時用到的參數(shù) private BigDecimal perFixInrate; //第二.三,四種情況時用到的參數(shù) private BigDecimal safeLine; //第三種情況用到的參數(shù) private BigDecimal capping; //第三種情況用到的參數(shù) private BigDecimal ladder1Rate; //第五種情況用到的參數(shù) private BigDecimal ladder1Max;//第五種情況用到的參數(shù) private BigDecimal ladder2Rate;//第五種情況用到的參數(shù) private BigDecimal ladder2Max;//第五種情況用到的參數(shù) private BigDecimal ladder3Rate;//第五種情況用到的參數(shù) private BigDecimal ladder3Max;//第五種情況用到的參數(shù) private BigDecimal ladder4Rate;//第五種情況用到的參數(shù) private BigDecimal ladder4Max;//第五種情況用到的參數(shù) // 省略部分代碼和getter,setter方法 }
如果分潤規(guī)則改變了,或者增加了新的分潤規(guī)則,這代碼就不知道要怎么維護了.
因此,基于這種情況,我按照給定的規(guī)則改寫了一下分潤規(guī)則.
修改原有規(guī)則,不會影響到其他規(guī)則
可以能很方便的新增新的分潤規(guī)則
改寫示例分潤接口由于該改寫程序只是一個測試程序,所以涉及的money都是用double,實際應(yīng)用中,要考慮精度,則需要改為BigDecimal
public interface ProfitRole { double getProfit(double money); }
分潤接口很簡單,就是傳入需要分潤的金額,然后計算出利潤返回
分潤類型public enum ProfitType { /** * 每筆固定收益1元,則填寫代理商收益1.00; */ FIXED_INCOME("^" + ProfitType.realNumber + "$"), /** * 每筆收益率為0.1%則填寫代理商收益0.1%; */ FIXED_RATE("^"+ ProfitType.rateNumber +"$"), /** * 每筆收益率為0.1%加上固定收益1元,則填寫代理商收益0.1%+1.00; */ FIXED_RATE_AND_FIXED_INCOME("^"+ ProfitType.rateNumber + "+" + ProfitType.realNumber + "$"), /** * 每筆收益率為0.1%,封頂3元,保底1元則填寫代理商收益1.00~0.1%~3.00; */ FIXED_RATE_AND_UPPER_LIMIT("^"+ ProfitType.realNumber + "~" + ProfitType.rateNumber + "~" + ProfitType.realNumber + "$"), /** * 梯度分潤 例如 0.1%<10000<0.2%<20000<0.3%<30000<0.5% * 少于10000 按照 0.1% 分潤 * 少于20000 按照 0.2% 分潤 * 少于30000 按照 0.3% 分潤 * 多于30000 按照 0.5% 分潤 */ GRADIENT_RATE("^"+ ProfitType.rateNumber+"(<"+ ProfitType.realNumber+"<"+ ProfitType.rateNumber+")+$"); // 非捕捉匹配正實數(shù) private static final String number = "(?:(?:[1-9]+d*)|(?:d))(?:.d+)?"; // 捕捉匹配正實數(shù) private static final String realNumber = "(" + number + ")"; // 捕捉匹配百分比 private static final String rateNumber = realNumber + "%"; public static Pattern getNumberPattern(){ return Pattern.compile(number); } private String pattern; ProfitType(String pattern) { this.pattern = pattern; } public Pattern getPattern() { return Pattern.compile(this.pattern); } }
分潤類型是一個枚舉類,構(gòu)造器參數(shù)是一個分潤表達式pattern,
其中ProfitType包含三個正則表達式:
number 匹配實數(shù),但不捕獲
realNumber 匹配實數(shù),并捕獲該實數(shù)
rateNumber 匹配百分比,只捕獲實數(shù),不捕獲百分號
五個枚舉值分別對應(yīng)五種分潤規(guī)則
FIXED_INCOME : 每筆固定收益1元,則填寫代理商收益1.00
FIXED_RATE : 每筆收益率為0.1%則填寫代理商收益0.1%
FIXED_RATE_AND_FIXED_INCOME : 每筆收益率為0.1%加上固定收益1元,則填寫代理商收益0.1%+1.00
FIXED_RATE_AND_UPPER_LIMIT : 每筆收益率為0.1%,封頂3元,保底1元則填寫代理商收益1.00~0.1%~3.00
GRADIENT_RATE : 梯度分潤 例如 0.1%<10000<0.2%<20000<0.3%<30000<0.5%
分潤實現(xiàn)類目前因為有五種分潤規(guī)則,每一個對應(yīng)一個實現(xiàn)類,因此有五個分潤實現(xiàn)類,與ProfitType的五種分潤規(guī)則一一對應(yīng)
FIXED_INCOME : FixedIncomeRole
FIXED_RATE : FixedRateRole
FIXED_RATE_AND_FIXED_INCOME : FixedRateAndFixedIncomeRole
FIXED_RATE_AND_UPPER_LIMIT : FixedRateAndUpperLimitRole
GRADIENT_RATE : GradientRateRole
分潤工廠類分潤實現(xiàn)類比較簡單,這里就不貼代碼了,有需要的上我[github](https://github.com/kco1989/ma...下載
最后在創(chuàng)建一個工廠,根據(jù)不同的ProfitType和分潤表達式,創(chuàng)建不同的分潤實現(xiàn)類
public final class ProfitRoleFactory { public static ProfitRole parseProfitRole(ProfitType type, String expression){ Matcher matcher = type.getPattern().matcher(expression); if (!matcher.matches()){ throw new RuntimeException("分潤表示時不符合" + type + "的規(guī)則."); } switch (type){ case FIXED_INCOME: return new FixedIncomeRole(Double.parseDouble(matcher.group(1))); case FIXED_RATE: return new FixedRateRole(Double.parseDouble(matcher.group(1))); case FIXED_RATE_AND_UPPER_LIMIT: return new FixedRateAndUpperLimitRole(Double.parseDouble(matcher.group(1)), Double.parseDouble(matcher.group(2)), Double.parseDouble(matcher.group(3))); case FIXED_RATE_AND_FIXED_INCOME: return new FixedRateAndFixedIncomeRole(Double.parseDouble(matcher.group(1)), Double.parseDouble(matcher.group(2))); case GRADIENT_RATE: List最后創(chuàng)建測試類測試rates = new ArrayList<>(); List limits = new ArrayList<>(); Pattern numberPattern = ProfitType.getNumberPattern(); Matcher numberMatcher = numberPattern.matcher(expression); for (int i = 0;numberMatcher.find();i ++){ if (i % 2 == 0){ rates.add(Double.parseDouble(numberMatcher.group())); }else{ limits.add(Double.parseDouble(numberMatcher.group())); } } return new GradientRateRole(rates, limits); default: //never come here return null; } } public static double getProfit(double money, ProfitType type, String expression){ ProfitRole profitRole = parseProfitRole(type, expression); if (profitRole != null){ return profitRole.getProfit(money); } return 0; } }
public class TestProfitRole { private static final List后記testDate = Arrays.asList(100.0,200.0,300.0,400.0,700.0, 1000.0,2000.0,3000.0,7000.0, 10000.0, 20000.0, 30000.0, 70000.0); @Test public void testFixedIncome(){ for (double data : testDate){ double profit = ProfitRoleFactory.getProfit(data, ProfitType.FIXED_INCOME, "1.00"); Assert.assertEquals(1.00, profit, 0.00001); } } @Test public void testFixedRate(){ for (double data : testDate){ double profit = ProfitRoleFactory.getProfit(data, ProfitType.FIXED_RATE, "0.1%"); Assert.assertEquals(data * 0.1 * 0.01, profit, 0.00001); } } @Test public void testFixedRateAndFixedIncome(){ for (double data : testDate){ double profit = ProfitRoleFactory.getProfit(data, ProfitType.FIXED_RATE_AND_FIXED_INCOME, "0.63%+3.00"); Assert.assertEquals(data * 0.63 * 0.01 + 3.0, profit, 0.00001); } } @Test public void testFixedRateAndUpperLimit(){ for (double data : testDate){ double profit = ProfitRoleFactory.getProfit(data, ProfitType.FIXED_RATE_AND_UPPER_LIMIT, "1.00~0.1%~3.00"); double actual = data * 0.1 * 0.01; if (actual < 1.0){ actual = 1.0; } if (actual > 3.0){ actual = 3.0; } Assert.assertEquals(actual, profit, 0.00001); } } @Test public void testGradientRate(){ for (double data : testDate){ double profit = ProfitRoleFactory.getProfit(data, ProfitType.GRADIENT_RATE, "0.1%<1000<0.2%<5000<0.3%<15000<0.5%"); if (data < 1000){ Assert.assertEquals(data * 0.01 * 0.1, profit, 0.00001); }else if (data < 5000){ Assert.assertEquals(data * 0.01 * 0.2, profit, 0.00001); }else if(data < 15000){ Assert.assertEquals(data * 0.01 * 0.3, profit, 0.00001); }else{ Assert.assertEquals(data * 0.01 * 0.5, profit, 0.00001); } } } }
現(xiàn)在回顧一下我們的目標,我們的目標是:
修改原有規(guī)則,不會影響到其他規(guī)則
可以能很方便的新增新的分潤規(guī)則
目標1是達成了,但是目標2卻有點差強人意.比如要新增一個分潤規(guī)則的話,除了新增分潤實現(xiàn)類外,還需要同時改ProfitType和ProfitRoleFactory類,沒有達到完全解耦.但相對之前的代碼還有有改進的.
這個問題先留個各位練習,后續(xù)有時間我再對該程序進行改進.
打賞現(xiàn)在已經(jīng)解決這個問題,已經(jīng)達到完全解耦了,詳情見使用抽象工廠模式實現(xiàn)各種不同分潤規(guī)則
如果覺得我的文章寫的還過得去的話,有錢就捧個錢場,沒錢給我捧個人場(幫我點贊或推薦一下)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/67062.html
摘要:本人郵箱歡迎轉(zhuǎn)載轉(zhuǎn)載請注明網(wǎng)址代碼已經(jīng)全部托管有需要的同學自行下載引言在上一篇文章中使用簡單工廠編寫不同的分潤規(guī)則遺留著一個問題那就是如果要新增分潤規(guī)則則需要修改原來的類也就是代碼沒有完全解耦因此在這一篇中我將分潤規(guī)則的設(shè)計改為抽象工廠模式 本人郵箱: 歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明網(wǎng)址 http://blog.csdn.net/tianshi_kcogithub: https://github...
摘要:安全透明輕量的螞蟻區(qū)塊鏈摩斯安全計算基礎(chǔ)設(shè)施螞蟻摩斯依托螞蟻金融科技平臺,結(jié)合區(qū)塊鏈技術(shù),將復(fù)雜的隱私保護與密碼學算法透明化產(chǎn)品化,提供安全發(fā)布安全模型安全統(tǒng)計安全查詢安全腳本等核心功能。 摘要:?螞蟻區(qū)塊鏈摩斯安全計算平臺針對數(shù)據(jù)安全信任、個人隱私保護以及數(shù)據(jù)基礎(chǔ)設(shè)施不足等痛點,秉持數(shù)據(jù)可用不可見和將計算移動到數(shù)據(jù)端的原則,借助區(qū)塊鏈、密碼學、隱私保護、安全多方計算、可信計算等前沿...
閱讀 1306·2021-11-23 09:51
閱讀 3421·2021-09-06 15:00
閱讀 996·2021-08-16 10:57
閱讀 1383·2019-08-30 12:46
閱讀 947·2019-08-29 12:22
閱讀 1615·2019-08-29 11:07
閱讀 3159·2019-08-26 11:23
閱讀 2993·2019-08-23 15:14