开具增值税发票建造者模式 + 原型模式

Posted 我是廖志伟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开具增值税发票建造者模式 + 原型模式相关的知识,希望对你有一定的参考价值。

文章目录

创建design-demo项目

项目代码:https://gitee.com/java_wxid/java_wxid/tree/master/demo/design-demo
项目结构如下(示例):

创建UserController

代码如下(示例):

package com.example.designdemo.controller;

import com.example.designdemo.pojo.TicketParam;
import com.example.designdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/25 19:26
 * @Description:
 */
@RestController
public class UserController 

    @Autowired
    private UserService userService;

    @PostMapping("/ticket")
    public Object getTicket(@RequestBody TicketParam ticketParam) 
        return userService.getTicket(ticketParam);
    



创建UserService

代码如下(示例):

package com.example.designdemo.service;

import com.example.designdemo.pojo.TicketParam;


/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/25 9:28
 * @Description:
 */

public interface UserService 

    Object getTicket(TicketParam ticketParam);


创建UserServiceImpl

代码如下(示例):

package com.example.designdemo.service.impl;

import com.example.designdemo.handler.SuggestRequirementHandlerProcess;
import com.example.designdemo.pojo.TicketParam;
import com.example.designdemo.pojo.UserInfo;
import com.example.designdemo.service.UserService;
import com.example.designdemo.ticket.builder.CompanyTicketBuilder;
import com.example.designdemo.ticket.builder.PersonalTicketBuilder;
import com.example.designdemo.ticket.builder.TicketBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService 

    @Autowired
    private SuggestRequirementHandlerProcess suggestRequirementHandlerProcess;

    //因为这部分是需要查询 缓存(如果缓存没有,需要查库)不应该写到 service层,但是为了代码书写简便
    //这部分我模拟在service 层。
    private UserInfo getUserInfo(String username) 
        return new UserInfo();
    

    public Object getTicket(TicketParam ticketParam) 
        TicketBuilder builder = null;
        String bankInfo = null;
        if(ticketParam.getBankInfo() != null) 
            bankInfo = "from 3rd party interface check.";
            builder = new CompanyTicketBuilder();
         else 
            builder = new PersonalTicketBuilder();
        
        builder.setParam(ticketParam.getAccount(), ticketParam.getTitle());
        String content = "from config center";
        String product = "from db";
        builder.setContent(content);
        builder.setProduct(product);
        builder.setBankInfo(bankInfo);
        // 详细的逻辑细节控制以及从配置中心或者是db中获取的逻辑步骤就是简单的 crud,自己明白即可
        return  builder.buildTicket();
    


创建TicketBuilder

代码如下(示例):

package com.example.designdemo.ticket.builder;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
public abstract class TicketBuilder<T> 
    public abstract void setParam(String account, String title);

    public abstract void setContent(String content); // 配置中心 或 DB 或缓存
    public abstract void setProduct(String product); // db
    public void setBankInfo(String bankInfo); //需要校验的,校验通过才能设置

    public abstract T buildTicket();


创建PersonalTicketBuilder

代码如下(示例):

package com.example.designdemo.ticket.builder;


import com.example.designdemo.ticket.TicketConstant;
import com.example.designdemo.ticket.pojo.PersonalTicket;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
public class PersonalTicketBuilder extends TicketBuilder<PersonalTicket> 

    private PersonalTicket personalTicket = TicketConstant.personalTicket.clone(); // new 关键字 改成clone的形式,只clone我们的
    // 不可变部分。对于可变部分和自定义用户提交部分,不进行clone

    @Override
    public void setParam(String account, String title) 
        personalTicket.setTitle(title);
        personalTicket.setAccount(account);
    

    @Override
    public void setContent(String content) 
        personalTicket.setContent(content);
    

    @Override
    public void setProduct(String product) 
        personalTicket.setProduct(product);
    

    @Override
    public PersonalTicket buildTicket() 
        return personalTicket;
    


创建CompanyTicketBuilder

代码如下(示例):

package com.example.designdemo.ticket.builder;


import com.example.designdemo.ticket.TicketConstant;
import com.example.designdemo.ticket.pojo.CompanyTicket;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
public class CompanyTicketBuilder extends TicketBuilder<CompanyTicket> 

    private CompanyTicket companyTicket = TicketConstant.companyTicket.clone(); // new 关键字

    @Override
    public void setBankInfo(String bankInfo) 
        companyTicket.setBankInfo(bankInfo);
    

    @Override
    public void setParam(String account, String title) 
        companyTicket.setTitle(title);
        companyTicket.setAccount(account);
    

    @Override
    public void setContent(String content) 
        companyTicket.setContent(content);
    

    @Override
    public void setProduct(String product) 
        companyTicket.setProduct(product);
    

    @Override
    public CompanyTicket buildTicket() 
        return companyTicket;
    


创建CompanyTicket

代码如下(示例):

package com.example.designdemo.ticket.pojo;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
public class CompanyTicket implements Cloneable
    private String type;
    private String footer;

    private String content; //配置中心 或者 DB里边获取。(缓存里获取,只不过如果万一DB 或配置中心有修改,需要同时更新缓存)
    private String product; //大部分情况db里获取(缓存里是有一些热门产品的)
    private String bankInfo; //校验我们的银行卡信息(通过我们的第三方银行相关接口进行的校验)

    private String account;
    private String title;

    public String getFooter() 
        return footer;
    

    public void setFooter(String footer) 
        this.footer = footer;
    

    public String getTitle() 
        return title;
    

    public void setTitle(String title) 
        this.title = title;
    

    public String getType() 
        return type;
    

    public void setType(String type) 
        this.type = type;
    

    public String getAccount() 
        return account;
    

    public void setAccount(String account) 
        this.account = account;
    

    public String getContent() 
        return content;
    

    public void setContent(String content) 
        this.content = content;
    

    public String getProduct() 
        return product;
    

    public void setProduct(String product) 
        this.product = product;
    

    public String getBankInfo() 
        return bankInfo;
    

    public void setBankInfo(String bankInfo) 
        this.bankInfo = bankInfo;
    

    @Override
    public CompanyTicket clone() 
        CompanyTicket companyTicket = null;
        try 
            companyTicket = (CompanyTicket) super.clone();
         catch (CloneNotSupportedException e) 
            e.printStackTrace();
        
        return companyTicket;
    


创建PersonalTicket

代码如下(示例):

package com.example.designdemo.ticket.pojo;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
public class PersonalTicket implements Cloneable
    private String type;
    private String footer;

    private String content; //配置中心 或者 DB里边获取。(缓存里获取,只不过如果万一DB 或配置中心有修改,需要同时更新缓存)
    private String product; //大部分情况db里获取(缓存里是有一些热门产品的)

    private String account; // 接口入参获取
    private String title;  // 接口入参获取

    public String getFooter() 
        return footer;
    

    public void setFooter(String footer) 
        this.footer = footer;
    

    public String getTitle() 
        return title;
    

    public void setTitle(String title) 
        this.title = title;
    

    public String getType() 
        return type;
    

    public void setType(String type) 
        this.type = type;
    

    public String getAccount() 
        return account;
    

    public void setAccount(String account) 
        this.account = account;
    

    public String getContent() 
        return content;
    

    public void setContent(String content) 
        this.content = content;
    

    public String getProduct() 
        return product;
    

    public void setProduct(String product) 
        this.product = product;
    

    @Override
    public PersonalTicket clone() 
        PersonalTicket personalTicket = null;
        try 
            personalTicket = (PersonalTicket) super.clone();
         catch (CloneNotSupportedException e) 
            e.printStackTrace();
        
        return personalTicket;
    


创建TicketConstant

代码如下(示例):

package com.example.designdemo.ticket;


import com.example.designdemo.ticket.pojo.CompanyTicket;
import com.example.designdemo.ticket.pojo.PersonalTicket;

public class TicketConstant 
    // 保存只具有公共属性的对象,供clone使用。
    public static PersonalTicket personalTicket = new PersonalTicket();
    public static CompanyTicket companyTicket = new CompanyTicket();

    static 
        personalTicket.setType("type");
        personalTicket.setFooter("footer");
        companyTicket.setType("type");
        companyTicket.setFooter("footer");
    


校验是否正常工作

以上是关于开具增值税发票建造者模式 + 原型模式的主要内容,如果未能解决你的问题,请参考以下文章

开具增值税发票建造者模式 + 原型模式

开具增值税发票建造者模式 + 原型模式

java设计模式3.建造者模式原型模式

设计模式之原型模式与建造者模式详解和应用

《设计模式之禅》--设计模式大PK

GoF 23 种设计模式之原型模式和建造者模式