设计模式之-工厂模式

一、工厂方法模式

工厂模式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.实例类定义部分

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

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

import com.le.ISender;

public class MailSenderImpl implements ISender {

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

}

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

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

import com.le.ISender;

public class SmsSenderImpl implements ISender {

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

}

4.工厂类定义部分

/**
 * 消息发送工厂类,用于根据条件初始化一个具体工人实例
 */
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.测试部分

/**
 * 测试类
 */
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

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

个人不推荐这种用法,原因与多工厂方法模式一样,代码重用率很低!

二、抽象工厂模式

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

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

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

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

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

时间: 2024-10-25 18:46:44

设计模式之-工厂模式的相关文章

设计模式-抽象工厂模式(C#)

设计模式--抽象工厂模式(JAVA) 在抽象工厂模式中,一个具体工厂可以生产一组相关的具体产品,这样的一组产品成为产品族,产品族中的每一个产品都属于某一个产品继承等等级结构.当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构.属于不同类型的具体产品时就可以使用抽象工厂模式. 抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建,当一个工

JS 设计模式(工厂模式环境搭建)

<!--引入的核心JS文件--> <script type="text/javascript" src="CommonUtil.js"></script> <script type=text/javascript charset=utf-8> <!--JS设计模式(工厂模式)--> //搭建一个工厂环境 //卖车店 function CarShop(){}; CarShop.prototype={ cons

设计模式 5 —— 工厂模式

设计模式目录: 设计模式 1 ——观察者模式 设计模式 2 —— 装饰者模式 设计模式 3 —— 迭代器和组合模式(迭代器) 设计模式 4 —— 迭代器和组合模式(组合) 设计模式 5 —— 工厂模式 设计模式 5 -- 工厂模式,布布扣,bubuko.com

php设计模式:工厂模式

意图: 定义一个用于创建对象的接口,让子类决定实例化哪一个类. 工厂模式实现: 工厂模式中任何创建对象的工厂类都要实现这个接口,实现接口的方法体中都要实现接口中的方法,它声明了工厂方法,该方法返回一个Product类型的对象. 工厂模式适用场景:1.当一个类不知道它所必须创建的对象的类的时候2.当一个类希望由它的子类来指定它所创建的对象的时候3.当类将创建对象的职责委托给多个帮助子类的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候 实例: <?php /** * 抽象工厂角色 *

浅析JAVA设计模式之工厂模式(一)

1 工厂模式简介 工厂模式的定义:简单地说,用来实例化对象,代替new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式可以动态决定将哪一个类实例化,不用先知道每次要实例化哪一个类. 工厂模式可以分一下三种形态: 简单工厂 (Simple Factory)模式:又称静态工厂模式(StaticFactory). 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory). 抽象工厂 (Abstract Factroy)模式:又称工具箱模式

浅析JAVA设计模式之工厂模式(二)

1 工厂方法模式简介 工厂方法 (Factroy Method) 模式:又称多态性工厂模式(Polymorphic Factory),在这种模式中,核心工厂不再是一个具体的类,而是一个抽象工厂,提供具体工厂实现的接口,具体创建产品交由子工厂去做,抽象工厂不涉及任何产品被实例化的细节.而不同等级的产品,就对应一个不同等级的工厂,如下图. 图1 1.1工厂方法模式(多态性工厂模式): 工厂方法模式有三个角色: 1. 抽象产品接口 2. 具体产品类 3. 抽象工厂接口 4.具体工厂类. 1.2工厂方法

设计模式之工厂模式 (二)

工厂模式分为三大类 简单工厂(SimpleFactory) 工厂方法模式(Factory Method) 抽象工厂模式(Abstract Factory) 动态工厂(Dynamic Factory,属于优化版简单工厂) 一.简单工厂 组成如下: (1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑.在java中它往往由一个具体类实现. (2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口.在java中由接口或者抽象类来实现. (3) 具体产品角色:工厂类所创建的对象就是此

浅谈php设计模式(1)---工厂模式

一.接口继承直接调用 先看看这样一段代码: 1 <?php 2 3 interface db{ 4 function conn(); 5 } 6 7 class dbmysql implements db { 8 public function conn(){ 9 echo "连接到了mysql"; 10 } 11 } 12 13 class dbsqlite implements db{ 14 public function conn(){ 15 echo "连接到了

5分钟理解设计模式之工厂模式

工厂模式是Java中最常用的设计模式.工厂模式提供很好的创建对象的方式,属于创建型模式. 使用工厂模式创建对象是不向使用者暴露创建细节,并且可以通过统一的接口引用对象. 实现 我们将创建Shape接口和实现Shape接口的具体类.下一步再声明工厂类ShapeFactory. 示例类FactoryPatternDemo使用ShapeFactory获取Shape对象.通过给ShapeFactory传递图形参数(CIRCLE / RECTANGLE / SQUARE)来获取需要的对象. 第1步 创建一

浅析JAVA设计模式之工厂模式(三)

在阅读本文之前,请先阅读(一)和(二)中的简单工厂模式和工厂方法模式. 1抽象工厂模式简介 抽象工厂 (Abstract Factroy) 模式:工具箱模式(kit).抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态,如下图. 图1.1 上图左边有一个工厂类的等级结构,右边有两个不同的产品等级结构,分别是产品A的等级结构和产品B的等级结构,工厂1和工厂2分别负责不同一个产品等级,同一个产品族的产品的生产.又例如下图: 图1.2 上图表示的是Button和Text两个不同产品的等级