简单工厂存在一个问题:类的创建依赖于工厂类,也就是说如果想拓展程序,必须对工厂类进行修改,这违背了闭包原则。
注:
闭包原则是设计模式的总原则,也称之为开闭原则,也就是说对扩展开发,对修改关闭。即程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有代码,实现一个热插拔的效果。
也就是说:为了使程序的扩展性好,易于维护和升级,要想达到这样的效果,需要使用接口和抽象类等。
工厂方法模式:创建一个工厂接口和创建多个工厂实现类,这样一旦需要增加新的功能,直接新增其它工厂实现类就可以,不需要修改之前的代码
第1步、创建一个Sender接口
package com.cn.factory.sender.impl;
/**
* 发送接口
* */
public interface Sender {
//发送方法
public void send();
}
第2步、创建发送短信和发送邮件实现类,实现Sender接口
发送邮件实现类
package com.cn.factory.sender;
import com.cn.factory.sender.impl.Sender;
/**
* 邮件发送实现类
* */
public class EmailSender implements Sender {
@Override
public void send() {
System.out.println("这是发送邮件的方法");
}
}
发送短信实现类
package com.cn.factory.sender;
import com.cn.factory.sender.impl.Sender;
/**
* 短信发送实现类
* */
public class SmsSender implements Sender {
/**
* 发送短信的方法
* */
@Override
public void send() {
System.out.println("这是发送短信的方法");
}
}
第3步、创建一个Provider接口
package com.cn.factory.sender.impl;
public interface Provider {
public Sender produce();
}
第4步、创建提供生产方法接口的实现类SmsSendFactory和EmailSendFactory,即邮件发送和短信发送的工厂实现类
邮件发送工厂实现类
package com.cn.factory.sender;
import com.cn.factory.sender.impl.Provider;
import com.cn.factory.sender.impl.Sender;
/**
* 发送邮件工厂实现类
* */
public class SendMailFactory implements Provider {
//生产方法
@Override
public Sender produce() {
return new EmailSender();
}
}
短信发送工厂实现类
package com.cn.factory.sender;
import com.cn.factory.sender.impl.Provider;
import com.cn.factory.sender.impl.Sender;
/**
* 发送短信工厂类
* */
public class SendSmsFactory implements Provider {
//生产方法
@Override
public Sender produce() {
return new SmsSender();
}
}
第5步、测试
package com.cn.factory.sender.test;
import com.cn.factory.sender.SendFactory;
import com.cn.factory.sender.SendMailFactory;
import com.cn.factory.sender.impl.Provider;
import com.cn.factory.sender.impl.Sender;
public class FactoryTest {
public static void main(String[] args) {
Provider provider=new SendMailFactory();
Sender sender=provider.produce();
sender.send();
}
}
总结:
工厂方法模式相比简单工厂模式而言好处在于:扩展性好。
比如你想实现发送QQ消息,只需要写一个发送QQ消息的实现类,实现Sender接口,同时写一个发送QQ消息的工厂类,实现Provider接口。而无需去改动现成的代码,这样做扩展性好。