设计模式之-工厂模式和抽象工厂模式

1、工厂方法模式(Factory Method):就是定义了一个创建对象的接口,但是由子类决定要实例化的类是那个。工厂方法让类把实例推迟到子类,工厂方法模式通过子类决定创建的对象是什么,来达到对对象创建过程的封装。
举个栗子:比如说 发送短信和邮件 ,我们可以定义一个统一的接口来发送邮件和短信。子类来实现这个接口进而进行不同的发送操作。
首先创建一个发送接口类,然后一个发送方法
设计模式之-工厂模式和抽象工厂模式_第1张图片
2、邮件类和短信类分别 实现这个接口类
邮件类
设计模式之-工厂模式和抽象工厂模式_第2张图片
短信类
设计模式之-工厂模式和抽象工厂模式_第3张图片
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();  
	}
}

测试结果如下
设计模式之-工厂模式和抽象工厂模式_第4张图片
虽然这种方式可以创建工厂模式,但如果增加一个实现类是我需要去修改工厂类中代码所以 不符合对 开闭原则。所以我们可以另一种方式来创建

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();
	}

}

测试结果设计模式之-工厂模式和抽象工厂模式_第5张图片
使用这种方式比第一种相比下要好,因为第一种方法如果传入的参数出错了就不能正确的创建对象。而多工厂方法 能提供多个方法 分别创建对象。 不过这种方式需要创建多个实例。所以我们可以使用 静态工厂模式去创建。

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();
	}
}

测试结果
设计模式之-工厂模式和抽象工厂模式_第6张图片
从上面三种方式来说 第一种如果传入的参数 有误那么不会正确创建对象,第二种需要实例化工厂类,所以一般使用静态工厂方法模式。 一般的 工厂模式用在有大量的产品创建时并需要共同的接口 那么可以使用工厂模式。

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();
 }
}

测试结果
设计模式之-工厂模式和抽象工厂模式_第7张图片
抽象工厂模式的好处就是 ,如果想增加一个功能及时发送消息 则只需要实现一个类然后再创建 一个工厂类 实现相应的接口就可以了。不需要去修改现有的代码 这样扩展性比较好

你可能感兴趣的:(设计模式)