在维护一批服务器时,经常遇到不同环境要用不同配置的情况。比如测试机用的是模拟邮件服务,生产机得连真实的SMTP服务器。每次上线前手动改代码,容易出错还费时间。
问题来了:硬编码太麻烦
以前写代码,直接在主逻辑里 new 一个服务实例:
MailService service = new MailService();
后来发现测试环境不该发真实邮件,就改成加个判断:
MailService service;
if ("prod".equals(env)) {
service = new RealMailService();
} else {
service = new MockMailService();
}
看起来没问题,可一旦要加短信、钉钉通知,判断逻辑就越堆越多,主代码越来越乱。
工厂模式来救场
不如把“创建实例”这件事单独拎出来,交给一个专门的类去做。这就是工厂模式的核心——解耦对象的使用和创建。
写个简单的工厂类:
public class NotificationFactory {
public static NotificationService create(String type, String env) {
if ("mail".equals(type)) {
return "prod".equals(env) ?
new RealMailService() : new MockMailService();
} else if ("sms".equals(type)) {
return "prod".equals(env) ?
new RealSmsService() : new MockSmsService();
}
throw new IllegalArgumentException("不支持的类型");
}
}
现在主逻辑清爽了:
NotificationService mail = NotificationFactory.create("mail", env);
mail.send("服务器重启了");
实际运维中的好处
上个月我们做灰度发布,一部分机器走新通知逻辑。只要在配置文件里加个 type 字段,工厂自动创建对应实例,不用动业务代码。出了问题回滚也快,改个配置就行。
还有一次,安全组要求禁用外网请求,测试环境所有第三方调用都要 mock。因为用了工厂,我们只改了一行配置,批量重启服务就搞定,没去每台机器上改代码。
工厂模式不是花架子,它让代码更经得起折腾。服务器那么多,环境那么杂,能少改代码就少改,省下的时间够喝两杯咖啡。