设计模式之-工厂模式

1、工厂方法模式java

工厂模式1:普通工厂方法模式闭包

1.常量定义部分学习

/**
 * 常量定义类,全部公用的常量定义均在此类中定义
 */
package com.le.global;

public class Const {
	/**
	 * 定义不一样工人类型的常量
	 */
	public static final byte SENDER_MAIL = 1;
	public static final byte SENDER_SMS = 2;

}

2.实例接口定义部分
测试

/**
 * 发送者接口定义,全部工人通用的方法都定义在这里,由具体工人类实现对应方法
 */

package com.le;

public interface ISender {
	public void send();
}

3.实例类定义部分spa

3.1邮件发送实例类定义部分.net

/**
 * 邮件发送工人具体类,实现邮件发送的具体内容
 */
package com.le.impl;

import com.le.ISender;

public class MailSenderImpl implements ISender {

	public void send() {
		System.out.println("Mail.send");
	}

}

3.2短信发送实例类定义部分code

/**
 * 短信发送工人具体类,实现短信发送的具体内容
 */
package com.le.impl;

import com.le.ISender;

public class SmsSenderImpl implements ISender {

	public void send() {
		System.out.println("SMS.send");
	}

}

4.工厂类定义部分
orm

/**
 * 消息发送工厂类,用于根据条件初始化一个具体工人实例
 */
package com.le;

import com.le.global.Const;
import com.le.impl.MailSenderImpl;
import com.le.impl.SmsSenderImpl;

public class SenderFactory {

	/**
	 * 传入类型,返回一个具体的工人
	 * 
	 * @param AType
	 * @return 若找到对应类型则直接返回一个新的对应工人实例,不然返回null
	 */
	public static ISender produce(int AType) {
		switch (AType) {
		case Const.SENDER_MAIL:
			return new MailSenderImpl();
		case Const.SENDER_SMS:
			return new SmsSenderImpl();
		default:
			System.out.println("类型未定义,请输入一个合法的类型");
			return null;
		}
	}
}

5.测试部分blog

/**
 * 测试类
 */
package com.le;

import com.le.global.Const;

public class Main {
	private static ISender sender = null;
	public static void main(String[] args) {
		// 邮件发送
		sender = SenderFactory.produce(Const.SENDER_MAIL);
		sender.send();

		// 短信发送
		sender = SenderFactory.produce(Const.SENDER_SMS);
		sender.send();
	}
}

6.输出内容接口

Mail.send
SMS.send


从上面的代码咱们能够看到,咱们在实际使用的时候,只须要把实例接口基类ISender、加工厂类SenderFactory定义好便可。而后在具体使用的时候,针对每一种不一样操做,实现ISender接口,实现本身的具体send方法;而后在SenderFactory.produce方法中增长一种针对该类型的实例化的返回值便可。而不须要对使用者Main.main方法中的逻辑作任何更改。

这个模式的优势:

  1. 新增一个新的实现类时,使用者逻辑不用作任何改动,扩展方便

  2. 逻辑清晰,业务与实现分离

缺点:

  1. 新增一个新的实现类时,须要同步修改加工厂类,违反了闭包原则

应用场景:在有大量的实现类,而且具备共同的接口时,能够考虑使用工厂方法模式进行建立。


工厂模式2:多工厂方法模式

1.改变工厂类定义部分

 /**
	 * 返回一个发送邮件的工人实例
	 * 
	 * @return
	 */
	public ISender produceMail() {
		return new MailSenderImpl();
	}

	/**
	 * 返回一个发送短信的工人实例
	 * 
	 * @return
	 */
	public ISender produceSms() {
		return new SmsSenderImpl();
	}

2.改变调用部分

public static void main(String[] args) {
		//定义工厂类
		SenderFactory sf = new SenderFactory();
		// 邮件发送
		sender = sf.produceMail();
		sender.send();

		// 短信发送
		sender = sf.produceSms();
		sender.send();
	}

3.输出内容

Mail.send
SMS.send

多工厂方法模式与普通工厂模式的区别就是:

普通工厂模式在须要具体实体的时候须要传入一个标识,工厂类根据传入的标识初始化一个对应的实体并返回,有可能传入的标识不合法,致使返回null。

多工厂方法模式是为每一个不一样的实体类定义了一个方法,这样在使用时绝对不会出错。

我的不推荐这种用法,由于这样实体类比较多的时候会致使代码重用率很低,你们了解一下就能够了!

工厂模式3:静态工厂方法模式

1.改变工厂类定义部分

         /**
	 * 返回一个发送邮件的工人实例
	 * 
	 * @return
	 */
	public static ISender produceMail() {
		return new MailSenderImpl();
	}

	/**
	 * 返回一个发送短信的工人实例
	 * 
	 * @return
	 */
	public static ISender produceSms() {
		return new SmsSenderImpl();
	}

2.改变调用部分

public static void main(String[] args) {
		// 邮件发送
		sender = SenderFactory.produceMail();
		sender.send();

		// 短信发送
		sender = SenderFactory.produceSms();
		sender.send();
	}

3.输出内容

Mail.send
SMS.send


该模式与多工厂方法模式的区别仅仅是把每一个获取实例的方法定义成为一个静态方法,调用时不须要初始化工厂类便可直接获取须要的实例

我的不推荐这种用法,缘由与多工厂方法模式同样,代码重用率很低!

2、抽象工厂模式

1.工厂接口定义部分

/**
 * 工厂接口,全部工厂类实现该类接口
 */
package com.le;

public interface ISenderFactory {
	public ISender produce();
}

2.工厂类定义部分

2.1邮件发送工厂类定义部分

/**
 * 邮件发送工厂类
 */
package com.le.factory;

import com.le.ISender;
import com.le.ISenderFactory;
import com.le.impl.MailSenderImpl;

public class MailSenderFactory implements ISenderFactory {

	public ISender produce() {
		return new MailSenderImpl();
	}

}

2.2.短信发送工厂类定义部分

/**
 * 短信发送工厂类
 */
package com.le.factory;

import com.le.ISender;
import com.le.ISenderFactory;
import com.le.impl.SmsSenderImpl;

public class SmsSenderFactory implements ISenderFactory {

	public ISender produce() {
		return new SmsSenderImpl();
	}

}

3.发送者接口定义部分

/**
 * 发送者接口定义,全部工人通用的方法都定义在这里,由具体工人类实现对应方法
 */

package com.le;

public interface ISender {
	public void send();
}

4.实例类定义部分

4.1.邮件发送实例类定义部分

/**
 * 邮件发送工人具体类,实现邮件发送的具体内容
 */
package com.le.impl;

import com.le.ISender;

public class MailSenderImpl implements ISender {

	public void send() {
		System.out.println("Mail.send");
	}

}

4.2.短信发送实例类定义部分

/**
 * 短信发送工人具体类,实现短信发送的具体内容
 */
package com.le.impl;

import com.le.ISender;

public class SmsSenderImpl implements ISender {

	public void send() {
		System.out.println("SMS.send");
	}

}

5.测试部分

/**
 * 测试类
 */
package com.le;

import com.le.factory.MailSenderFactory;
import com.le.factory.SmsSenderFactory;

public class Main {
	private static ISender sender = null;
	private static ISenderFactory sf = null;
	public static void main(String[] args) {
		//建立邮件发送工厂实例
		sf = new MailSenderFactory();
		//获取邮件发送实例
		sender = sf.produce();
		//调用发送方法
		sender.send();
		
		//建立短信发送工厂实例
		sf = new SmsSenderFactory();
		//获取实例
		sender = sf.produce();
		//发送消息
		sender.send();
	}
}

6.输出内容

Mail.send
SMS.send

从上面的代码咱们能够知道,抽象工厂模式与普通工厂方法模式的区别:抽象工厂模式是对普通工厂方法模式的进一层封装

不过就算是抽象工厂模式,在每新增一个新的功能时,都须要扩展调用部分,使其支持新增的实例。

我的总结:在遇到一个须要实例化不少实例,而且每一个实例在使用时都有共同的特性时,能够考虑使用工厂模式编写代码。推荐使用普通工厂方法来实现,不过须要在获取实例的方法内要作判断,若获得非法值给予默认处理或友好的反馈给调用者。

以上学习资料来自原帖地址

相关文章
相关标签/搜索