戏说设计模式-工厂方法

继上一次经理当面把发邮件、发短信的代码改成工厂模式后,过去了1个月。这一天,小杨找到老罗问:“今天销售问我,用户注册的时候,发邮件的协议是什么?”

“销售问你?他关心这个干吗?”老罗不明白销售并不懂技术,怎么会问这个问题。

“我也不知道,可能是客户问他的吧?他说客户注册后收不到邮件,他们公司只支持POP3协议,猜想可能跟这个有关系”小杨说。

“哦,那我看看代码”,老罗打开了SimpleSenderFactory 这个类,“暂时只支持SMTP协议,那我把POP3加上”。于是老罗把SimpleSenderFactory 改成这样

public class SimpleSenderFactory {

    public enum SENDER_TYPE{
        MAIL_SMTP,SMS,MAIL_POP3
    }

    public static Sender product(SENDER_TYPE senderType){
        if(senderType == SENDER_TYPE.SMS){
            return new SmsSender();

        }else if(senderType == SENDER_TYPE.MAIL_SMTP){
            MailSender mailSender = new MailSender();
            mailSender.config("smtp.gmail.com","true","true","password");
            return mailSender;
        }else if(senderType == SENDER_TYPE.MAIL_POP3){
            MailSender mailSender = new MailSender();
            mailSender.config("pop.gmail.com","true","true","password");
            return mailSender;
        }else{
		return null;
        }
    }
}


同时让小杨也修改了调用的地方。

过了几天,小杨说产品部门说,鉴于上次客户要求加入POP3协议的问题,干脆把IMAP协议也加上吧,老罗把SimpleSenderFactory改了一次。

又过了几天,小杨说:销售上次演示说没收到邮件,让查一下。老罗联系了销售和客户,发现这家客户的邮件服务器是不能加密的,老罗把SimpleSenderFactory改了一次。

这一天,小杨对老罗说:“hi,你那代码能否再加一个发送站内消息的功能?”

“啥,站内信?你以为我这代码是屠龙刀呢,什么都能干,啥玩意都往这里面加,三天两头的改东西,要加你自己加去”,老罗显然是厌倦了,有些不满

“你有气冲销售、产品说去撒啊,我只是写了一个注册功能,后台不都是你写的吗,你那有缺陷,大家好像都以为是我弄的呢”。

“什么叫有缺陷,你给我说清楚”

“有缺陷就是垃圾代码,老子就是说清楚了,怎么了”

“咋的了,又吵起来了,有话好好说!”经理及时制止住了这次纠纷,并且让老罗加上了发站内信的代码,让他改好了马上上线。

第二天,不断有客服反映,很多用户注册收不到短信,老罗忙了一早上,发现是近期频繁修改SimpleSenderFactory这个类,最后一次匆忙上线影响到了发短信的代码。

因为这次事件导致了用户十几个小时内无法注册,成为一次事故,经理把老罗叫到办公室:“你是怎么搞得客服的投诉电话都打到我这里了”

“小杨老是让我改代码啊,上次又催的急,他自己都没测试发短信的功能”,老罗说。

都是久经考验的老员工了,怎么思想还这么不成熟,你自己的代码不牢牢控制在自己的手中,出了问题还推卸责任”,经理变了脸色

“我知道了,下次注意,不过现在这情况以后也会出现啊,我每次修改发邮件的功能,或者添加一个新的什么功能,都要修改那个类”,老罗发现经理不好糊弄,转移了话题。

经理重新查看了SimpleSenderFactory,说:“嗯,形势发生了改变,频繁修改MailSender类,但MMSSender基本上不修改,我们应该为每一个类型的Sender子类增加一个工厂类”

首先定义一个工厂接口

public interface SenderFactory {

    Sender product();
}

发邮件的工厂类实现工厂接口

public class MailSenderFactory implements SenderFactory{

    public Sender product(){

        MailSender mailSender = new MailSender();
        mailSender.config("smtp.gmail.com","true","true","password");
        return mailSender;

    }
}

发短信的工厂类实现工厂接口

public class SMSSenderFactory implements SenderFactory{

    public Sender product(){

        return new SmsSender();

    }
}

“这样,我们把发邮件、发短信的实例化隔离开来,以后其中某一个修改不会对其他的产生影响”

调用的时候

MailSenderFactory mailSenderFactory = new MailSenderFactory();
Sender mailSender = mailSenderFactory.product();
mailSender.send("j3@tm.com","j4@tm.com","你好","欢迎");

类图变成了这样


工厂类SenderFactory把创建Sender的工作延迟给具体的子类,比如MailSender,以后修改发邮件的相关代码,不会影响其他的比如发短信的代码。即使新增一个发站内信的功能也不会影响其他的功能。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值