当前位置:网站首页>Lottery DDD code

Lottery DDD code

2022-06-23 05:38:00 duanmy0687

Anemia model

Prize pool and Awards

class AwardPool {
    
    int awardPoolId;
    List<Award> awards;
    public List<Award> getAwards() {
    
        return awards;
    }
  
    public void setAwards(List<Award> awards) {
    
        this.awards = awards;
    }
    ......
}

class Award {
    
   int awardId;
   int probability;// probability 
  
   ......
}

To design a LotteryService, Among them drawLottery() Method to write service logic

//sql Inquire about , Map data to AwardPool object 
AwardPool awardPool = awardPoolDao.getAwardPool(poolId);

for (Award award : awardPool.getAwards()) {
    
   // Find a match for award.getProbability() Probabilistic award
}

DDD Project realization

1. Bound context ( I.e. module )

Generally, a module is used to represent the bounding context of a domain

import com.company.team.bussiness.lottery.*;// Lottery context 
import com.company.team.bussiness.riskcontrol.*;// Risk control context 
import com.company.team.bussiness.counter.*;// Count context 
import com.company.team.bussiness.condition.*;// Activity access context 
import com.company.team.bussiness.stock.*;// Inventory context 

Organizational structure within the module
For the organizational structure within the module , In general, we are based on domain objects 、 Field service 、 Domain Repository 、 Anticorrosive coating and other organization methods .

import com.company.team.bussiness.lottery.domain.valobj.*;// Domain object - The value object 
import com.company.team.bussiness.lottery.domain.entity.*;// Domain object - Entity 
import com.company.team.bussiness.lottery.domain.aggregate.*;// Domain object - Aggregate root 
import com.company.team.bussiness.lottery.service.*;// Field service 
import com.company.team.bussiness.lottery.repo.*;// Domain Repository 
import com.company.team.bussiness.lottery.facade.*;// Field coating 

2. Domain object

 Insert picture description here

Luck draw (DrawLottery) Aggregate roots and prize pools (AwardPool) The value object

Lottery aggregate root : Of the raffle id、 List of all available prize pools under this activity ,
One of its main domain functions is based on a lucky draw scenario (DrawLotteryContext), Choose an appropriate prize pool , namely chooseAwardPool Method .

chooseAwardPool The logic of :DrawLotteryContext It will carry the scene information of the user's lottery ( The city in which the score or draw was made ),DrawLottery According to the scene information , Match one that can award users AwardPool.

package com.company.team.bussiness.lottery.domain.aggregate;
import ...;
  
public class DrawLottery {
    
    private int lotteryId; // Luck draw id
    private List<AwardPool> awardPools; // The prize pool list 
  
    //getter & setter
    public void setLotteryId(int lotteryId) {
    
        if(id<=0){
    
            throw new IllegalArgumentException(" Illegal lottery id"); 
        }
        this.lotteryId = lotteryId;
    }
  
    // According to the lottery context Choose the prize pool 
    public AwardPool chooseAwardPool(DrawLotteryContext context) {
    
        if(context.getMtCityInfo()!=null) {
    
            return chooseAwardPoolByCityInfo(awardPools, context.getMtCityInfo());
        } else {
    
            return chooseAwardPoolByScore(awardPools, context.getGameScore());
        }
    }
     
    // Select the prize pool according to the city where the lottery is located 
    private AwardPool chooseAwardPoolByCityInfo(List<AwardPool> awardPools, MtCifyInfo cityInfo) {
    
        for(AwardPool awardPool: awardPools) {
    
            if(awardPool.matchedCity(cityInfo.getCityId())) {
    
                return awardPool;
            }
        }
        return null;
    }
  
    // Choose the prize pool according to the score of the lucky draw 
    private AwardPool chooseAwardPoolByScore(List<AwardPool> awardPools, int gameScore) {
    ...}
}

After matching to a specific prize pool , Need to determine what the final prize to the user is . The domain function of this part is AwardPool Inside .

package com.company.team.bussiness.lottery.domain.valobj;
import ...;
  
public class AwardPool {
    
    private String cityIds;// Cities supported by prize pools 
    private String scores;// Bonus pool support score 
    private int userGroupType;// The type of user the prize pool matches 
    private List<Awrad> awards;// Prizes included in the prize pool 
  
    // Whether the current prize pool matches the city 
    public boolean matchedCity(int cityId) {
    ...}
  
    // Whether the current bonus pool matches the user's score 
    public boolean matchedScore(int score) {
    ...}
  
    // Choose the prize pool according to the probability 
    public Award randomGetAward() {
    
        int sumOfProbablity = 0;
        for(Award award: awards) {
    
            sumOfProbability += award.getAwardProbablity();
        }
        int randomNumber = ThreadLocalRandom.current().nextInt(sumOfProbablity);
        range = 0;
        for(Award award: awards) {
    
            range += award.getProbablity();
            if(randomNumber<range) {
    
                return award;
            }
        }
        return null;
    }
}

Compared with the past only getter、setter Different business objects , Domain objects have behaviors , The object is fuller . meanwhile , Instead of writing this logic in a service ( for example **Service), Domain functions are more cohesive , Responsibilities are clearer .

3. The repository

Repository, The overall external access to the repository is provided by Repository Provide
database , Distributed cache , Local cache

// Database resources 
import com.company.team.bussiness.lottery.repo.dao.AwardPoolDao;// Database access object - Jackpot 
import com.company.team.bussiness.lottery.repo.dao.AwardDao;// Database access object - Prize 
import com.company.team.bussiness.lottery.repo.dao.po.AwardPO;// Database persistence objects - Prize 
import com.company.team.bussiness.lottery.repo.dao.po.AwardPoolPO;// Database persistence objects - Jackpot 
  
import com.company.team.bussiness.lottery.repo.cache.DrawLotteryCacheAccessObj;// Distributed cache access objects - Lottery cache access 
import com.company.team.bussiness.lottery.repo.repository.DrawLotteryRepository;// Repository access objects - Lottery resource pool 
package com.company.team.bussiness.lottery.repo;
import ...;
  
@Repository
public class DrawLotteryRepository {
    
    @Autowired
    private AwardDao awardDao;
    @Autowired
    private AwardPoolDao awardPoolDao;
    @AutoWired
    private DrawLotteryCacheAccessObj drawLotteryCacheAccessObj;
  
    public DrawLottery getDrawLotteryById(int lotteryId) {
    
        DrawLottery drawLottery = drawLotteryCacheAccessObj.get(lotteryId);
        if(drawLottery!=null){
    
            return drawLottery;
        }
        drawLottery = getDrawLotteyFromDB(lotteryId);
        drawLotteryCacheAccessObj.add(lotteryId, drawLottery);
        return drawLottery;
    }
  
    private DrawLottery getDrawLotteryFromDB(int lotteryId) {
    ...}
}

4. Anticorrosive coating

In a context , Sometimes you need to access the external context .

package com.company.team.bussiness.lottery.facade;
import ...;
  
@Component
public class UserCityInfoFacade {
    
    @Autowired
    private LbsService lbsService;// City information for external users RPC service 
     
    public MtCityInfo getMtCityInfo(LotteryContext context) {
    
        LbsReq lbsReq = new LbsReq();
        lbsReq.setLat(context.getLat());
        lbsReq.setLng(context.getLng());
        LbsResponse resp = lbsService.getLbsCityInfo(lbsReq);
        return buildMtCifyInfo(resp);
    }
  
    private MtCityInfo buildMtCityInfo(LbsResponse resp) {
    ...}
}

5. Field service

package com.company.team.bussiness.lottery.service.impl
import ...;
  
@Service
public class LotteryServiceImpl implements LotteryService {
    
    @Autowired
    private DrawLotteryRepository drawLotteryRepo;
    @Autowired
    private UserCityInfoFacade UserCityInfoFacade;
    @Autowired
    private AwardSendService awardSendService;
    @Autowired
    private AwardCounterFacade awardCounterFacade;
  
    @Override
    public IssueResponse issueLottery(LotteryContext lotteryContext) {
    
        DrawLottery drawLottery = drawLotteryRepo.getDrawLotteryById(lotteryContext.getLotteryId());// Get the lottery configuration aggregate root 
        awardCounterFacade.incrTryCount(lotteryContext);// Add lucky draw count information 
        AwardPool awardPool = lotteryConfig.chooseAwardPool(bulidDrawLotteryContext(drawLottery, lotteryContext));// Pick the prize pool 
        Award award = awardPool.randomChooseAward();// Pick the prize 
        return buildIssueResponse(awardSendService.sendAward(award, lotteryContext));// Send out the prize entity 
    }
  
    private IssueResponse buildIssueResponse(AwardSendResponse awardSendResponse) {
    ...}
}
package ...;
  
import ...;
  
@Service
public class LotteryApplicationService {
    
    @Autowired
    private LotteryRiskService riskService;
    @Autowired
    private LotteryConditionService conditionService;
    @Autowired
    private LotteryService lotteryService;
     
    // Users participate in the lottery 
    public Response<PrizeInfo, ErrorData> participateLottery(LotteryContext lotteryContext) {
    
        // Verify user login information 
        validateLoginInfo(lotteryContext);
        // Verify risk control  
        RiskAccessToken riskToken = riskService.accquire(buildRiskReq(lotteryContext));
        ...
        // Activity access check 
        LotteryConditionResult conditionResult = conditionService.checkLotteryCondition(otteryContext.getLotteryId(),lotteryContext.getUserId());
        ...
        // Draw and return results 
        IssueResponse issueResponse = lotteryService.issurLottery(lotteryContext);
        if(issueResponse!=null && issueResponse.getCode()==IssueResponse.OK) {
    
            return buildSuccessResponse(issueResponse.getPrizeInfo());
        } else {
       
            return buildErrorResponse(ResponseCode.ISSUE_LOTTERY_FAIL, ResponseMsg.ISSUE_LOTTERY_FAIL)
        }
    }
  
    private void validateLoginInfo(LotteryContext lotteryContext){
    ...}
    private Response<PrizeInfo, ErrorData> buildErrorResponse (int code, String msg){
    ...}
    private Response<PrizeInfo, ErrorData> buildSuccessResponse (PrizeInfo prizeInfo){
    ...}
} 
原网站

版权声明
本文为[duanmy0687]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206230341415317.html