实战!通过简单工厂模式实现功能

简介: 实战!通过简单工厂模式实现功能

一 故事背景

项目中要实现一个功能,功能具体为,选择不同的邮件名称,产生不同的邮件模板。
功能图例

image.png

二 设计

实现思路上,想到了通过简单工厂模式,简单工厂模式只关心产出的产品不关心实现过程,只需要传入一个类型吗,就能得到想要的结果,十分符合开闭原则。下面是该功能的UML类图

image.png

首先,定义一个抽象的父类 IShMessageEmailService
然后定义实现类 ShMessageEmailEtaService 及 ShMessageEmailEtdService
最后定义工厂类 ShipMessageEmailFactory 工厂类接受一个类型码参数,用来判定产生哪个产品。

三 实现

public interface IShMessageEmailService {
    public String getMessageText(ShDynamic dynamic, SailingSchedule sailingSchedule, String messageType);
}


@Service
public class ShMessageEmailEtaService extends BusinessService implements IShMessageEmailService {

    @Autowired
    private ShManifestCargoService shManifestCargoService;
    @Autowired
    private ShipPortService shipPortService;

    @Override
    public String getMessageText(ShDynamic dynamic, SailingSchedule sailingSchedule, String messageType) {
        ShManifestCargo shManifestCargo = shManifestCargoService.findImpCargoAndBlNo(sailingSchedule.getId());
        String loadPortCode = "";
        String loadPortName = "";
        String dischargePortCode = "";
        String dischargePortName = "";
        String loadPortCnName = "";
        String dischargePortCnName = "";
        String cargoDesc = "";
        String blNo = "";
        BigDecimal grossWeight = new BigDecimal(0);
        if (shManifestCargo != null) {
            if (shManifestCargo.getCargoDesc() != null) {
                cargoDesc = shManifestCargo.getCargoDesc();
            }
        }
        //装货港
        if (shManifestCargo != null) {
            blNo = shManifestCargo.getBlNo();
            if (shManifestCargo.getGrossWeight() != null) {
                grossWeight = shManifestCargo.getGrossWeight();
            }
            loadPortCode = shManifestCargo.getLoadPortCode();
            dischargePortCode = shManifestCargo.getDischargePortCode();
            if (loadPortCode != null) {
                ShipPort shipPort = shipPortService.findByPortCode(loadPortCode);
                loadPortName = shipPort.getName();
                if (shipPort.getCountryCode() != null) {
                    loadPortCnName = shipPort.getCountryCode();
                }
            }
            if (dischargePortCode != null) {
                ShipPort shipPort = shipPortService.findByPortCode(dischargePortCode);
                dischargePortName = shipPort.getName();
                if (shipPort.getCountryCode() != null) {
                    dischargePortCnName = shipPort.getCountryCode();
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        sb.append("Dear " + (sailingSchedule.getFirstClientName() == null ? "" : sailingSchedule.getFirstClientName()) + "\n");
        sb.append("\n");
        sb.append("Mt. Morning Calm " + sailingSchedule.getShipEnName() + "\n");
        sb.append("=== Cargo: " + cargoDesc + "=== \n");

        if ("".equals(loadPortCode) || "".equals(loadPortCnName)) {
            sb.append("Port of Loading: " + loadPortName + loadPortCnName + "\n");
        } else {
            sb.append("Port of Loading: " + loadPortName + "," + loadPortCnName + "\n");
        }
        if ("".equals(dischargePortCode) || "".equals(dischargePortCnName)) {
            sb.append("Port of Discharging: " + dischargePortName + dischargePortCnName + "\n");
        } else {
            sb.append("Port of Discharging: " + dischargePortName + "," + dischargePortCnName + "\n");
        }
        if ("".equals(blNo)) {
            if (grossWeight.compareTo(new BigDecimal(0)) == 0) {
                sb.append("B/L Quantity: \n");

            } else {
                sb.append("B/L Quantity:" + grossWeight + "KGS\n");
            }
        } else {
            if (grossWeight.compareTo(new BigDecimal(0)) == 0) {
                sb.append("B/L Quantity:" + blNo + "\n");

            } else {
                sb.append("B/L Quantity:" + blNo + "," + grossWeight + "KGS\n");
            }
        }
        sb.append("\n");
        sb.append("--/-/-   Arrived Guishan p/stn\n");
        sb.append("--/-/-   Dropped anchor & NOR tendered\n");
        sb.append("--/-/-   POB\n");
        // 靠泊时间
        sb.append("--/-/-   First line ashored\n");
        // ALL FAST
        sb.append("--/-/-   All line fasted at wharf No.4\n");
        // 开始联检时间
        sb.append("--/-/-   Free pratique granted\n");
        // 开工时间
        sb.append("--/-/-   Estimated time of discharging commence\n");
        // 预计完工时间
        sb.append("--/-/-   Estimated time of discharging complete\n");
        // 预计离泊时间
        sb.append("--/-/-   ETD (Subject to discharging & Main Channel traffic control) \n");
        sb.append("\n");
        sb.append("Arrival conditions:\n");
        // 抵港油水FO DO FW
        BigDecimal arrvFo = dynamic.getArrvFo();
        BigDecimal arrvDo = dynamic.getArrvDo();
        BigDecimal arrvFw = dynamic.getArrvFw();
        sb.append("Bunker - FO:" + (arrvFo == null ? "" : arrvFo) + "MTS/DO:" + (arrvDo == null ? "" : arrvDo) + "MTS/FW:" + (arrvFw == null ? "" : arrvFw) + "MTS \n");
        // 抵港吃水F A
        BigDecimal arrvDraughtf = dynamic.getArrvDraughtf();
        BigDecimal arrvDraughta = dynamic.getArrvDraughta();
        sb.append("Draft -  F:" + (arrvDraughtf == null ? "" : arrvDraughtf) + "M/A:" + (arrvDraughta == null ? "" : arrvDraughta) + "M \n");
        sb.append("\n");
        sb.append("Remark:\n");
        sb.append("1.Vessel can (un)berth at Xiaohu terminal only in daytime.\n");
        sb.append("2.Vessel can (un)berth only against ebb tide.\n");
        sb.append("3.Two tugboats assist berthing. \n");
        sb.append("\n");
        sb.append("Thank you for your kind agency appointment.If any inquries pls be free let me know. \n");
        sb.append("We respectfully remind you to also email the relevant information to the operator in charge of this voyage and do not reply this system email. \n");
        return sb.toString();
    }
}

@Service
public class ShMessageEmailEtdService extends BusinessService implements IShMessageEmailService {

    @Autowired
    private ShManifestCargoService shManifestCargoService;
    @Autowired
    private ShipPortService shipPortService;

    @Override
    public String getMessageText(ShDynamic dynamic, SailingSchedule sailingSchedule, String messageType) {
        ShManifestCargo shManifestCargo = shManifestCargoService.findExpCargoAndBlNo(sailingSchedule.getId());
        String loadPortCode = "";
        String loadPortName = "";
        String dischargePortCode = "";
        String dischargePortName = "";
        String loadPortCnName = "";
        String dischargePortCnName = "";
        String cargoDesc = "";
        String blNo = "";
        BigDecimal grossWeight = new BigDecimal(0);
        if(shManifestCargo!=null){
            if(shManifestCargo.getCargoDesc()!=null){
                cargoDesc = shManifestCargo.getCargoDesc();
            }
        }

        //装货港
        if (shManifestCargo!=null) {
            blNo = shManifestCargo.getBlNo();
            if(shManifestCargo.getGrossWeight()!=null){
                grossWeight = shManifestCargo.getGrossWeight();
            }
            loadPortCode = shManifestCargo.getLoadPortCode();
            dischargePortCode = shManifestCargo.getDischargePortCode();
            if (loadPortCode != null) {
                ShipPort shipPort = shipPortService.findByPortCode(loadPortCode);
                loadPortName = shipPort.getName();
                if(shipPort.getCountryCode()!=null){
                    loadPortCnName = shipPort.getCountryCode();
                }
            }
            if (dischargePortCode != null) {
                ShipPort shipPort = shipPortService.findByPortCode(dischargePortCode);
                dischargePortName = shipPort.getName();
                if(shipPort.getCountryCode()!=null){
                    dischargePortCnName = shipPort.getCountryCode();
                }
            }
        }
        StringBuilder sb = new StringBuilder();
        sb.append("Dear " + (sailingSchedule.getFirstClientName() == null ? "" : sailingSchedule.getFirstClientName()) + "\n");
        sb.append("\n");
        sb.append("Mt. Morning Calm " + sailingSchedule.getShipEnName() + "\n");
        sb.append("=== Cargo: " + cargoDesc + "=== \n");

        if ("".equals(loadPortCode) || "".equals(loadPortCnName)) {
            sb.append("Port of Loading: " + loadPortName + loadPortCnName + "\n");
        } else {
            sb.append("Port of Loading: " + loadPortName + "," + loadPortCnName + "\n");
        }
        if ("".equals(dischargePortCode) || "".equals(dischargePortCnName)) {
            sb.append("Port of Discharging: " + dischargePortName + dischargePortCnName + "\n");
        } else {
            sb.append("Port of Discharging: " + dischargePortName + "," + dischargePortCnName + "\n");
        }
    //        sb.append("Pls B Advd Abv Vsl's Arriving Conditon Asfs:\n");
        if ("".equals(blNo)) {
            if(grossWeight.compareTo(new BigDecimal(0))==0) {
                sb.append("B/L Quantity: \n");

            }else{
                sb.append("B/L Quantity:"+ grossWeight + "KGS\n");
            }
        }else{
            if(grossWeight.compareTo(new BigDecimal(0))==0) {
                sb.append("B/L Quantity:" + blNo + "\n");

            }else{
                sb.append("B/L Quantity:" + blNo + "," + grossWeight + "KGS\n");
            }
        }
        sb.append("\n");
        sb.append("--/-/-   Arrived Guishan p/stn\n");
        sb.append("--/-/-   Dropped anchor & NOR tendered\n");
        sb.append("--/-/-   POB\n");
        // 靠泊时间
        sb.append("--/-/-   First line ashored\n");
        // ALL FAST
        sb.append("--/-/-   All line fasted\n");
        // 开始联检时间
        sb.append("--/-/-   Free pratique granted\n");
        // 开工时间
        sb.append("--/-/-   Hose on\n");
        // 预计完工时间
        sb.append("--/-/-   Discharging commenced\n");
        // 预计离泊时间
        sb.append("--/-/-   Discharging completed \n");
        sb.append("--/-/-   Vapour pushing completed \n");
        sb.append("--/-/-   Hose off \n");
        sb.append("--/-/-   Outbound pilot on board \n");
        sb.append("--/-/-   Sailed from Nansha \n");
        sb.append("--/-/-   ETA Tokuyama \n");
        sb.append("\n");
        sb.append("Arrival conditions:\n");
        // 抵港油水FO DO FW
        BigDecimal arrvFo = dynamic.getArrvFo();
        BigDecimal arrvDo = dynamic.getArrvDo();
        BigDecimal arrvFw = dynamic.getArrvFw();
        sb.append("Bunker - FO:" + (arrvFo == null ? "" : arrvFo) + "MTS/DO:" + (arrvDo == null ? "" : arrvDo) + "MTS/FW:" + (arrvFw == null ? "" : arrvFw) + "MTS\n");
        // 抵港吃水F A
        BigDecimal arrvDraughtf = dynamic.getArrvDraughtf();
        BigDecimal arrvDraughta = dynamic.getArrvDraughta();
        sb.append("Draft -  F:" + (arrvDraughtf == null ? "" : arrvDraughtf) + "M/A:" + (arrvDraughta == null ? "" : arrvDraughta) + "M\n");
        sb.append("\n");
        sb.append("Departure conditions:\n");

        // 离港油水FO DO FW
        BigDecimal deptFo = dynamic.getDeptFo();
        BigDecimal deptDo = dynamic.getDeptDo();
        BigDecimal deptFw = dynamic.getDeptFw();
        sb.append("Bunker - FO:" + (deptFo == null ? "" : deptFo) + "MTS/DO:" + (deptDo == null ? "" : deptDo) + "MTS/FW:" + (deptFw == null ? "" : deptFw) + "MTS \n");
        // 离港吃水F A
        BigDecimal deptDraughtf = dynamic.getDeptDraughtf();
        BigDecimal deptDraughta = dynamic.getDeptDraughta();
        sb.append("Draft -  F:" + (deptDraughtf == null ? "" : deptDraughtf) + "M/A:" + (deptDraughta == null ? "" : deptDraughta) + "M \n");
        sb.append("\n");
        sb.append("Remark:\n");
        sb.append("1.Vessel can (un)berth at Xiaohu terminal only in daytime.\n");
        sb.append("2.Vessel can (un)berth only against ebb tide.\n");
        sb.append("3.Two tugboats assist berthing. \n");
        sb.append("4.One tugboat assist unberthing. \n");
        sb.append("\n");
        sb.append("Thanks again for your kind agency appointment.If any inquries pls be free let me know.\n");
        sb.append("We respectfully remind you to also email the relevant information to the operator in charge of this voyage and do not reply this system email. \n");
        return sb.toString();
    }
}



@Service
public class ShipMessageEmailFactory {
    public static final String ETA_MESSAGE = "etaMessage";
    public static final String ETD_MESSAGE = "etdMessage";
    public static final String PROGRESS_MESSAGE = "progressMessage";
    @Autowired
    private ShMessageEmailEtaService shMessageEmailEtaService;
    @Autowired
    private ShMessageEmailEtdService shMessageEmailEtdService;

    public IShMessageEmailService createProduct(String messageType) {
        if (messageType.equals(ETA_MESSAGE)) {
            return shMessageEmailEtaService;
        } else if (messageType.equals(ETD_MESSAGE)) {
            return shMessageEmailEtdService;
        }
        return null;
    }
}

   //调用该方法
   @RequestMapping(value = "query_email_model", method = {RequestMethod.GET})
    public SailingQueryEntity queryEmailModel(@RequestParam("id") String id, @RequestParam("messageType") String messageType) {
        SailingQueryEntity entity = new SailingQueryEntity();
        SailingSchedule sailingSchedule = service.find(SailingSchedule.class, id);
        List<ShDynamic> dynamic = shipDynamicService.findBySailingScheduleId(id);
        ShDynamic dynamicEntity = dynamic.get(0);
        String text = "";
        if(!messageType.equals(shipMessageEmailFactory.PROGRESS_MESSAGE)){
            IShMessageEmailService shMessageEmailService = shipMessageEmailFactory.createProduct(messageType);
            text = shMessageEmailService.getMessageText(dynamicEntity, sailingSchedule, messageType);
        }
        entity.setArrivedText(text);
        return entity;
    }

需要注意的是,网上的简单工厂模式的工厂类例子都是使用static进行修饰,即静态方法。但是我在使用static进行修饰时,却报错,原因是,通过spring管理的service不是静态的,而静态方法,要求返回值必须是静态的才行,将static去掉可以了。

相关文章
|
7月前
|
人工智能 IDE 开发工具
JetBrains PyCharm 2025.1 发布 - 面向专业开发者的 Python IDE
JetBrains PyCharm 2025.1 (macOS, Linux, Windows) - 面向专业开发者的 Python IDE
753 29
JetBrains PyCharm 2025.1 发布 - 面向专业开发者的 Python IDE
|
7月前
|
Ubuntu Linux
在Ubuntu 22.04系统中如何将Cgroup v2切换为v1
需要注意的是,虽然Cgroup v1和v2在功能上有一些差异,但大多数用户可能并不需要关心这些差异。除非你有特殊的需求,或者你的应用程序需要使用Cgroup v1的特定功能,否则你可能并不需要切换Cgroup版本。在大多数情况下,使用系统默认的Cgroup版本就可以满足需求。
389 10
|
9月前
|
人工智能 自然语言处理 算法
接入DeepSeek需要做算法备案吗?一文读懂算法备案的那些事儿
在AI快速发展的今天,算法备案成为企业合规运营的关键。本文通过五个案例解析接入DeepSeek是否需备案:1) 微调模型需备案,流程4-6个月;2) 面向公众服务需备案;3) 内部使用通常无需备案;4) 个人自用无需备案;5) 面向特定专业人士通常无需备案。了解这些要求,确保企业在享受AI红利的同时合规运营,规避风险。
|
移动开发 小程序 安全
原生小程序Donut多端开发
随着移动应用开发的不断发展,跨平台开发成为了一个备受关注的话题。开发人员希望能够使用一套代码库,同时支持多个平台,从而提高开发效率并覆盖更广泛的用户群体。在小程序领域,微信 Donut 多端(也称为原生小程序 Donut 多端)为开发人员提供了一种全新的跨平台开发方式。本文将介绍 Donut 多端的概念、特点以及如何开始使用它来开发跨平台小程序。
470 0
|
11月前
|
弹性计算 负载均衡 监控
slb配置健康检查
slb配置健康检查
260 5
|
传感器 测试技术 芯片
基于STM32的环境监测系统 (esp8266)(上)
基于STM32的环境监测系统 (esp8266)(上)
2227 1
|
测试技术 数据库 数据安全/隐私保护
推荐一个牛逼的开源在线文档系统,支持Markdown和富文本编辑模式!
推荐一个牛逼的开源在线文档系统,支持Markdown和富文本编辑模式!
4159 0
推荐一个牛逼的开源在线文档系统,支持Markdown和富文本编辑模式!
|
网络安全 流计算 Python
实时计算 Flink版操作报错合集之Flink sql-client 针对kafka的protobuf格式数据建表,报错:java.lang.ClassNotFoundException 如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
380 1
|
Java
jvm性能调优 - 17案例实战_每日上亿请求量的电商系统 老轻代垃圾回收参数如何优化
jvm性能调优 - 17案例实战_每日上亿请求量的电商系统 老轻代垃圾回收参数如何优化
460 0
|
Shell Linux 数据安全/隐私保护
linux基本功系列之su命令
linux基本功系列之su命令
559 0
linux基本功系列之su命令