設計模式之-工廠模式

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

從上面的代碼咱們能夠知道,抽象工廠模式與普通工廠方法模式的區別:抽象工廠模式是對普通工廠方法模式的進一層封裝

不過就算是抽象工廠模式,在每新增一個新的功能時,都須要擴展調用部分,使其支持新增的實例。

我的總結:在遇到一個須要實例化不少實例,而且每一個實例在使用時都有共同的特性時,能夠考慮使用工廠模式編寫代碼。推薦使用普通工廠方法來實現,不過須要在獲取實例的方法內要作判斷,若獲得非法值給予默認處理或友好的反饋給調用者。

以上學習資料來自原帖地址

相關文章
相關標籤/搜索