1、工厂方法模式(Factory Method):就是定义了一个创建对象的接口,但是由子类决定要实例化的类是那个。工厂方法让类把实例推迟到子类,工厂方法模式通过子类决定创建的对象是什么,来达到对对象创建过程的封装。
举个栗子:比如说 发送短信和邮件 ,我们可以定义一个统一的接口来发送邮件和短信。子类来实现这个接口进而进行不同的发送操作。
首先创建一个发送接口类,然后一个发送方法
2、邮件类和短信类分别 实现这个接口类
邮件类
短信类
3、编写工厂类
package com.springmvc.headfrist.factorymethod;
/**
* 建造工厂类
*
*
* @author lenovo
*
*/
public class SendFactory {
//普通工厂方法模式
public Sender produce(String type) {
if ("mail".equals(type)) {
return new MailSender();
} else if ("sms".equals(type)) {
return new SmsSender();
} else {
System.out.println("请输入正确的类型!");
return null;
}
}
}
4、测试
public class FactoryTest {
/**
* @param args
*/
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.produce("sms");
sender.send();
}
}
测试结果如下
虽然这种方式可以创建工厂模式,但如果增加一个实现类是我需要去修改工厂类中代码所以 不符合对 开闭原则。所以我们可以另一种方式来创建
5、创建多个工厂方法模式 ,接口类和 实现类不变,只修改工厂类
package com.springmvc.headfrist.factorymethod;
/**
* 建造工厂类
*
*
* @author lenovo
*
*/
public class SendFactory {
//多个工厂方法模式
public Sender productMail()
{
return new MailSender();
}
public Sender productSms()
{
return new SmsSender();
}
}
测试
public class FactoryTest {
/**
* @param args
*/
public static void main(String[] args) {
SendFactory factory = new SendFactory();
Sender sender = factory.productMail();
sender.send();
}
}
测试结果
使用这种方式比第一种相比下要好,因为第一种方法如果传入的参数出错了就不能正确的创建对象。而多工厂方法 能提供多个方法 分别创建对象。 不过这种方式需要创建多个实例。所以我们可以使用 静态工厂模式去创建。
6、静态工厂模式
package com.springmvc.headfrist.factorymethod;
/**
* 建造工厂类
*
*
* @author lenovo
*
*/
public class SendFactory {
//静态工厂方法模式将上面的工厂模式里的方法置为静态的,不需要创建实例,直接调用即可
public static Sender productMail()
{
return new MailSender();
}
public static Sender productSms()
{
return new SmsSender();
}
}
测试
public class FactoryTest {
/**
* @param args
*/
public static void main(String[] args) {
Sender factory = SendFactory.productMail();
factory.send();
}
}
测试结果
从上面三种方式来说 第一种如果传入的参数 有误那么不会正确创建对象,第二种需要实例化工厂类,所以一般使用静态工厂方法模式。 一般的 工厂模式用在有大量的产品创建时并需要共同的接口 那么可以使用工厂模式。
7、抽象工厂模式相比 一般的工厂模式来说 ,工厂模式 类的创建需要依赖工厂类。如果要扩展那么就需要修改工厂类 这和开闭原则 矛盾。一般的 对扩展开放对修改关闭。所以 一般的工厂模式设计不好。那么我们可以使用抽象工厂模式来创建
定义一个接口
public interface Sender1 {
public void send();
}
实现类
public class SmsSender1 implements Sender1 {
@Override
public void send() {
System.out.println("this is sms sender!");
}
}
public class MailSender1 implements Sender1 {
@Override
public void send() {
System.out.println("this is mailsender!");
}
}
然后在定义一个接口,这个接口是用于访问sender1接口的。
public interface Provider {
public Sender1 produce();
}
定义工厂类 然后实现 该接口
public class SendMailFactory implements Provider{
@Override
public Sender1 produce() {
return new SmsSender1();
}
}
public class SendSmsFactory implements Provider {
@Override
public Sender1 produce() {
return new MailSender1();
}
}
测试
public class Test {
public static void main(String[] args) {
//实例化 工厂
Provider provider = new SendMailFactory();
// 调用工厂中方法
Sender1 sender = provider.produce();
//
sender.send();
}
}
测试结果
抽象工厂模式的好处就是 ,如果想增加一个功能及时发送消息 则只需要实现一个类然后再创建 一个工厂类 实现相应的接口就可以了。不需要去修改现有的代码 这样扩展性比较好