舉兩個例子以快速明白Java中的簡單工廠模式:
蘭州網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項目制作,到程序開發(fā),運(yùn)營維護(hù)。成都創(chuàng)新互聯(lián)公司成立與2013年到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運(yùn)維經(jīng)驗,來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。
女媧摶土造人
話說:“天地開辟,未有人民,女媧摶土為人。”女媧需要用土造出一個個的人,但在女媧造出人之前,人的概念只存在于女媧的思想里面。
女媧造人,這就是簡單工廠模式的應(yīng)用。
首先,在這個造人的思想里面,有幾個重要的角色:女媧本身、抽象的人的概念和女媧所造出的一個個具體的人。
1.)女媧是一個工廠類,也就是簡單工廠模式的核心角色。
2.)具休的一個個的人,包括張三,李四等。這些人便是簡單工廠模式里面的具體產(chǎn)品角色
3.)抽象的人是最早只存在于女媧的頭腦里的一個想法,女媧按照這個想法造出的一個個具體的人,便都符合這個抽象的人的定義。換言之,這個抽象的想法規(guī)定了所有具體的人必須都有的接口(特征或者功能)
其UML類圖出下所示:
理解了上面的這些東西,再來理解下面的例子,對照理解,相信看完這篇文章,便對java簡單工廠模式有一個很好的理解:
有一個農(nóng)場公司,專門向市場銷售各類水果,在這個系統(tǒng)里需要描述下列水果:
葡萄 Grape
草莓 Stuawberry
蘋果 Apple
水果與其他植物不同,最終可以采摘食用,那么一個自然的做法是建立一個各種水果都適用的接口,以便與其他農(nóng)場里的植物區(qū)分開來,
此時,則是為水果類聲明了一個接口,表現(xiàn)在代碼上:
1 public interface Fruit {
2 // 生長
3 void grow();
4 // 收獲
5 void harvest();
6 // 種植
7 void plant();
8 }
9
10
水果接口規(guī)定出所有的水果必須實現(xiàn)的接口,包括任何水果類必須具備的方法plant(),grow(),和harvest();
Apple類是水果類的一種,因此它實現(xiàn)了水果接口所聲明的所有方法。另處,由于蘋果是多年生植物,因此多出一個treeAge性質(zhì),描述蘋果的樹齡。代碼如下所示:
package fac;
public class Apple implements Fruit { // 通過implements實現(xiàn)接口Fruit
private int treeAge;
public void grow() {
log( " Apple is growing " );
}
public void harvest() {
log( " Apple has been harvested " );
}
public void plant() {
log( " Apple ha been planted " );
}
public static void log(String msg) {
System.out.println(msg);
}
public int getTreeAge() {
return treeAge;
}
public void setTreeAge( int treeAge) {
this .treeAge = treeAge;
}
}
同理,葡萄 Grape:
package fac;
public class Grape implements Fruit{
private boolean seedless;
public void grow(){
log("Grape is growing.");
}
public void harvest(){
log("Grape has been harvested");
}
public void plant(){
log("Grape ha been planted");
}
public static void log(String msg){
System.out.println(msg);
}
public boolean isSeedless() {
return seedless;
}
public void setSeedless(boolean seedless) {
this.seedless = seedless;
}
}
草莓 Stuawberry:
package fac;
public class Strawberry implements Fruit{
public void grow(){
log("Strawberry is growing");
}
public void harvest(){
log("Strawberry has been harvested");
}
public void plant(){
log("Strawberry has been planted");
}
public static void log(String msg){
System.out.println(msg);
}
}
農(nóng)場園丁也是系統(tǒng)的一部分,由一個類來代表,F(xiàn)ruitGardener類,代碼如下:
package fac;
public class FruitGardener{
public static Fruit factory(String which)throws Exception{
if(which.equalsIgnoreCase("apple")){
return new Apple();
}else if(which.equalsIgnoreCase("strawberry")){
return new Strawberry();
}else if (which.equalsIgnoreCase("grape")){
return new Grape();
}else{
throw new Exception("Bad fruit request");
}
}
}
這時有人來果園玩,和園丁說,給我們介紹下你的水果吧。于是園?。?/p>
package fac;
public class People {
public static void main(String[] args) throws Exception {
FruitGardener fg=new FruitGardener();
Fruit ap=fg.factory("Apple");
ap.grow();
Fruit gp=fg.factory("Grape");
gp.plant();
Fruit dd=fg.factory("ddd");//拋出Bad fruit request異常
}
}
(注:以上代碼在JDK5.0,Myeclise3.2下編譯通過)
類比兩個例子,園丁就相當(dāng)于女媧,而水果就相當(dāng)于具體的人,接口水果類就相當(dāng)于存在于類女媧思想里的人的抽象概念。
由以上兩個例子可得出,簡單工廠模式需要由以下角色組成:
接口
接口的實現(xiàn)類(簡單工廠模式里面的具體產(chǎn)品角色)
工廠
理解了以下兩個例子,再來看第三個例子:
注意對比以下三個實例的不同
實例1:
package org.jzkangta.factorydemo01;
//定義接口
interface Car{
public void run();
public void stop();
}
//具體實現(xiàn)類
class Benz implements Car{
public void run(){
System.out.println("Benz開始啟動了。。。。。");
}
public void stop(){
System.out.println("Benz停車了。。。。。");
}
}
//具體實現(xiàn)類
class Ford implements Car{
public void run(){
System.out.println("Ford開始啟動了。。。");
}
public void stop(){
System.out.println("Ford停車了。。。。");
}
}
//工廠
class Factory{
public static Car getCarInstance(){
return new Ford();
}
}
public class FactoryDemo01 {
public static void main(String[] args) {
Car c=Factory.getCarInstance();
c.run();
c.stop();
}
}
實例二:
package fac;
//定義接口
interface Car{
public void run();
public void stop();
}
//具體實現(xiàn)類
class Benz implements Car{
public void run(){
System.out.println("Benz開始啟動了。。。。。");
}
public void stop(){
System.out.println("Benz停車了。。。。。");
}
}
class Ford implements Car{
public void run(){
System.out.println("Ford開始啟動了。。。");
}
public void stop(){
System.out.println("Ford停車了。。。。");
}
}
//工廠
class Factory{
public static Car getCarInstance(String type){
Car c=null;
if("Benz".equals(type)){
c=new Benz();
}
if("Ford".equals(type)){
c=new Ford();
}
return c;
}
}
public class FactoryDemo02 {
public static void main(String[] args) {
Car c=Factory.getCarInstance("Benz");
if(c!=null){
c.run();
c.stop();
}else{
System.out.println("造不了這種汽車。。。");
}
}
}
實例三:
interface Car{
public void run();
public void stop();
}
class Benz implements Car{
public void run(){
System.out.println("Benz開始啟動了。。。。。");
}
public void stop(){
System.out.println("Benz停車了。。。。。");
}
}
class Ford implements Car{
public void run(){
System.out.println("Ford開始啟動了。。。");
}
public void stop(){
System.out.println("Ford停車了。。。。");
}
}
class Toyota implements Car{
public void run(){
System.out.println("Toyota開始啟動了。。。");
}
public void stop(){
System.out.println("Toyota停車了。。。。");
}
}
class Factory{
public static Car getCarInstance(String type){
Car c=null;
try {
c=(Car)Class.forName("org.jzkangta.factorydemo03."+type).newInstance();//利用反射得到汽車類型
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return c;
}
}
public class FactoryDemo03 {
public static void main(String[] args) {
Car c=Factory.getCarInstance("Toyota");
if(c!=null){
c.run();
c.stop();
}else{
System.out.println("造不了這種汽車。。。");
}
}
}
對比三個實例:
實例一,雖然實現(xiàn)了簡單工廠,但每次只能得到一種汽車,如果我們想換一種,就得修改工廠,太不方便,而實例二則改變了這種情況,便得我們可以按照我們的需要更換汽車,但我們所更換的汽車必須是實現(xiàn)類中有的,如果我們想要增加一種汽車的時候,我們還是得更改工廠,通過改進(jìn),實例三利用反射機(jī)制,得到汽車類型,這樣當(dāng)我們需要增加一種新的汽車時,就無需要再修改工廠,而只需要增加要實現(xiàn)的類即可。也就是說要增加什么樣的汽車直接增加這個汽車的類即可,而無需改變工廠。從而達(dá)到了工廠分離的效果。
這個應(yīng)該比較簡單一點(diǎn)。
某系統(tǒng)日志記錄器要求支持多種日志記錄方式,如文件記錄、數(shù)據(jù)庫記錄等,且用戶可以根據(jù)要求動態(tài)選擇日志記錄方式。現(xiàn)使用工廠方法模式設(shè)計該系統(tǒng),并寫出相應(yīng)Java代碼。
interface Log{
public void writeLog();
}
class FileLog implements Log{
public void writeLog(){
System.out.println("文件記錄");
}
}
class DatabaseLog implements Log{
public void writeLog(){
System.out.println("數(shù)據(jù)庫記錄");
}
}
interface LogFactory{
public Log createLog();
}
class FileLogFactory implements LogFactory{
public Log createLog(){
return new FileLog();
}
}
class DatabaseLogFactory implements LogFactory{
public Log createLog(){
return new DatabaseLog();
}
}
public class Client{
public static void main(String[] args) {
try{
Log log;
LogFactory factory;
//這里可以改成使用DOM和Java反射機(jī)制讀取XML文件,獲取工廠類名
factory=new DatabaseLogFactory ();
log=factory.createLog();
log.writeLog();
}
catch(Exception e){
System.out.println(e.getMessage());
}
}
}
interface Fruit { // 定義一個水果接口
public void eat(); // 吃水果
}
class Apple implements Fruit {
public void eat() {
System.out.println("** 吃蘋果。");
}
};
class Orange implements Fruit {
public void eat() {
System.out.println("** 吃橘子。");
}
};
class Factory { // 定義工廠類
private static Factory factory;
private Factory(){}
public static Factory getInstance() {
if(factory==null){
factory=new Factory();
}
return factory;
}
public Apple newApplet(){
return new Apple();
}
public Orange newOrange(){
return new Orange();
}
};
class FactoryModel {
public static void main(String args[]) {
Fruit f = Factory.getInstance().newApplet();
if (f != null) { // 判斷是否取得實例
f.eat();
}
f = Factory.getInstance().newOrange();
if (f != null) { // 判斷是否取得實例
f.eat();
}
}
};
工廠方法模式分為三種:
1、普通工廠模式,就是建立一個工廠類,對實現(xiàn)了同一接口的一些類進(jìn)行實例的創(chuàng)建
2、多個工廠方法模式,是對普通工廠方法模式的改進(jìn),在普通工廠方法模式中,如果傳遞的字符串出錯,則不能正確創(chuàng)建對象,而多個工廠方法模式是提供多個工廠方法,分別創(chuàng)建對象。
3、靜態(tài)工廠方法模式,將上面的多個工廠方法模式里的方法置為靜態(tài)的,不需要創(chuàng)建實例,直接調(diào)用即可。
具體代碼請參考:java設(shè)計模式? ?第三大節(jié)
如果對您有幫助,請及時采納謝謝