下面對問題解決內容分三種:不使用工廠模式;使用簡單工廠模式;使用工廠模式。
題目:
寶馬(BMW)和奔馳(Benz)汽車都由汽車工廠生產,爲兩種品牌的汽車提供一個工廠(簡單工廠)生產這兩種品牌的汽車。現汽車工廠進行改革,寶馬工廠專門生產寶馬汽車,奔馳工廠專門生產奔馳汽車。對簡單工廠模式的汽車工廠進行分割,使用工廠方法模式模擬特定的工廠生產特定品牌的汽車。要求在實現時引入配置文件,使得整個系統具有靈活性和可擴展性,方便未來增加新的工廠。
不使用工廠模式:
package xyq.car;
/**
*這個是不使用工程模式的代碼
* 新建一個接口,叫Factory
* 接口內有一個方法,叫create(),等待被繼承
* @author Rigel小闊耐
*
*/
public interface Factory {
public void create();
}
package xyq.car;
/**
* 構建一個BMW類,繼承Factory接口
* 實現create方法,輸出(生產寶馬汽車)
* @author Rigel小闊耐
*
*/
public class BMW implements Factory {
@Override
public void create() {
// TODO Auto-generated method stub
System.out.println("生產寶馬汽車");
}
}
package xyq.car;
/**
* 構建一個Benz類,繼承Factory接口
* 實現create方法,輸出(生產奔馳汽車)
* @author Rigel小闊耐
*
*/
public class Benz implements Factory {
@Override
public void create() {
// TODO Auto-generated method stub
System.out.println("生產奔馳汽車");
}
}
package xyq.car;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 構造一個測試類
* @author Rigel小闊耐
*
*/
public class NoFactory {
public static void main(String[] args) {
// TODO Auto-generated method stub
Factory fact = null;
String carBrand = getBrand();
if(carBrand.equalsIgnoreCase("BMW")) {
System.out.println("汽車公司正在生產汽車");
fact = new BMW();
}else if(carBrand.equalsIgnoreCase("Benz")) {
System.out.println("汽車公司正在生產汽車");
fact = new Benz();
}else {
System.out.println("當前未生產此品牌的汽車");
}
fact.create();
}
public static String getBrand() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("請輸入汽車品牌");
String str = strin.readLine();
return str;
}catch(IOException e) {
e.printStackTrace();
return "";
}
}
}
運行結果:
使用簡單工程模式:
package xyq.car.simple;
/**
* 簡單工程類(不滿足開閉原則)
* @author Rigel小闊耐
*
*/
public class SimpleFactory {
public static Factory produceCar(String carBrand) {
Factory fact = null;
System.out.println("使用簡單工廠模式");
if(carBrand.equalsIgnoreCase("BMW")) {
System.out.println("汽車工廠生產寶馬汽車");
return new BMW();
}else if(carBrand.equalsIgnoreCase("Benz")){
System.out.println("汽車工廠生產奔馳汽車");
return new Benz();
}else {
System.out.println("當前爲生產此品牌的汽車");
}
return fact;
}
}
package xyq.car.simple;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 測試一下簡單工廠類
* @author Rigel小闊耐
*
*/
public class SimpleText {
public static void main(String[] args) {
// TODO Auto-generated method stub
Factory fact = null;
String carBrand = getBrand();
try {
fact = SimpleFactory.produceCar(carBrand);
}catch(Exception e) {
e.printStackTrace();
}
fact.create();
}
public static String getBrand() {
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("請輸入汽車的品牌:");
String str = strin.readLine();
return str;
}catch(IOException e) {
e.printStackTrace();
return "";
}
}
}
運行結果:
使用工廠模式:
建立一個工廠接口:
package xyq.car.factory;
public interface CarFactory {
public Factory produceCar();
}
建立兩個具體工廠:
package xyq.car.factory;
public class BenzFactory implements CarFactory {
@Override
public Factory produceCar() {
// TODO Auto-generated method stub
System.out.println("Benz工廠生產Benz汽車。");
return new Benz();
}
}
package xyq.car.factory;
public class BMWFactory implements CarFactory {
public Factory produceCar() {
System.out.println("BMW工廠生產BMW汽車。");
return new BMW();
}
}
客戶端測試:
package xyq.car.factory;
public class FactoryText3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("使用工廠方法模式");
CarFactory carFactory;
Factory fact = null;
carFactory = (CarFactory)XMLUtil.getBean();
fact = carFactory.produceCar();
fact.create();
}
}
配置文件(+反射機制)實現開閉原則
<?xml version="1.0" encoding="UTF-8"?>
<config>
<className>xyq.car.factory.BMWFactory</className>
</config>
package xyq.car.factory;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
public class XMLUtil {
//該方法用於從XML配置文件中提取具體類類名,並返回一個實例對象
public static Object getBean()
{
try
{
//創建文檔對象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("src/xyq/car/factory/config.xml"));
//獲取包含類名的文本節點
NodeList nl = doc.getElementsByTagName("className");
Node classNode=nl.item(0).getFirstChild();
String cName=classNode.getNodeValue();
//通過類名生成實例對象並將其返回
Class<?> c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
}
運行結果(無需輸入,自動生成):
注:
不使用工廠模式和使用簡單工廠模式兩個代碼都是純Java,後期通過輸入,得出結果。工廠模式需要有配置文件(+反射機制),因爲我沒有設置變量,所以結果無需輸入,自動顯示。寫得很粗糙,歡迎指正,留言都會回覆。