java模式之工厂模式
package com.mode.factory;
/**
*工厂模式,我再刚刚接触这个模式的时候很纳闷,这样不是很复杂了吗?而且有很多限制。
*其实工厂模式是用在比如数据库连接之类的地方的,生产出来的产品都是一样的,就是有个产品的父类,下面代码中我会详细解释一下每句都是干什么用的。
*
*下面的几个类提前说明一下:
*SampleFactory类:工厂类,用来创建产品,这也是这个模式的核心,所有的类都出自本类的一个方法
*Sample类:产品的抽象类,工厂中生产出来的所有产品,也就是工厂类的create方法返回的所有类都将是继承该抽象类的子类,这个类在工厂模式中也是必须的
*Sample_Box和Sample_Ball类:这就是产品了,既然是产品还可以有很多个,比如还可以写Sample_Bucket等很多的类出来,但是这些子类一定要继承Sample,并且实现父类的所有方法,工厂创建出来的产品都是统一的。
*/
public class SampleFactory{
/**
*这个方法用来生产产品,也就是调用该方法或者一个类,这个类是继承过Sample的子类
*@author Mars.CN
*@param type 传入参数用来选择哪个返回哪个子类
*@return 返回一个Sample类型的实例,Sample是个父类,由他派生出子类来
*/
public static Sample create(int type){
if(type==1){
return new Sample_Box();
}else if(type==2){
return new Sample_Ball();
}else{
return null;
}
}
//当然,这里你也可以写一些其他的方法,比如带参数的之类的
}
package com.mode.factory;
/**
*产品的抽象类,所有的产品都将继承这个类
*在这个泪中所有的方法都是抽象的,等待他的子类去实现他们。
*这里看你都需要一些什么方法,如果这里没有提到的方法,那么到了子类中即使写了,工厂产生出来的产品也显示不了这些方法
*/
public abstract class Sample{
public abstract double getPrice();//产品的单价
public abstract String getColor();//产品的颜色
public abstract String getIntro();//产品的介绍
}
package com.mode.factory;
/**
*实现了Sample的一个子类,也就是一个产品
*/
public class Sample_Box extends Sample{
public double getPrice(){
//实现该方法
return 100;
}
public String getColor(){
//实现该方法
return "blue";
}
public String getIntro(){
//实现该方法
return "这是一个蓝色的盒子";
}
}
package com.mode.factory;
/**
*实现了Sample的一个子类,也就是一个产品
*/
public class Sample_Ball extends Sample{
private double price = 125;
private String color = "yello";
private String intro = "这是一个黄色的球";
public double getPrice(){
//实现该方法
return price;
}
public String getColor(){
//实现该方法
return color;
}
public String getIntro(){
//实现该方法
return intro;
}
}
package com.mode.factory;
/**
*一个测试类,将告诉你这个模式怎么使用
*/
public class Factory_Test{
public static void main(String[] args){
//工厂创建产品的方法是静态的,所以没必要实例化这个工厂,或者你干脆在工厂里面写一个私有的构造方法,禁止实例化工厂
Sample sample1 = SampleFactory.create(1);//获得Sample_Box的那个子类,记住,前面接受的时候一定要用父类类型,这样才能,如果还用子类的,那工厂就没什么意义了,干脆直接new好了。
System.out.println("工厂模式测试");
System.out.println("-------------------------------------");
System.out.println("介绍:" + sample1.getIntro());
System.out.println("单价:" + sample1.getPrice());
System.out.println("颜色:" + sample1.getColor());
System.out.println("-------------------------------------");
Sample sample2 = SampleFactory.create(2);//获得Sample_Ball那个子类的实例
System.out.println("介绍:" + sample2.getIntro());
System.out.println("单价:" + sample2.getPrice());
System.out.println("颜色:" + sample2.getColor());
System.out.println("-------------------------------------");
}
}
下面再写一个工厂模式的扩展……
package com.mode.factory.daofactory.factory;
import com.mode.factory.daofactory.connection.DAOConnection;
import com.mode.factory.daofactory.exception.DAOException;
import java.sql.Connection;
/**
*工厂模式的扩展,用来创建数据库连接的东西,不同于上一个工厂模式的是,这里的产品(子类)都是靠动态加载上去的。
*/
public class DAOFactory{
/**
*创建一个连接,用于连接各种不同的数据库
*@author Mars.CN
*@param strConn 这个是子类的具体位置,比如com.mode.factory.daofactory.connection.SQLConnection
*@return 返回一个DAOConnection类型的连接对象
*@exception 如果提取类失败则抛出这个异常,简单写一下,明白这个意思就行了。
*/
public static Connection getConnection(String strConn) throws DAOException{
try{
DAOConnection conn = (DAOConnection)Class.forName(strConn).newInstance();
return conn.getConnection();
//上面这个方法是动态加载一个类,并或者该类的一个实例,其实在连接数据库的时候我们也有用到。
}catch(Exception e){
throw new DAOException(strConn,e.getMessage());
}
}
}
package com.mode.factory.daofactory.exception;
/**
*连接异常类,意思一下,明白意思就可以了
*如果自己要写的话最好写详细点
*/
public class DAOException extends Exception{
String strExceptionConn;
String strErrorMessage;
public DAOException(String strConn,String strMsg){
strExceptionConn = strConn;
strErrorMessage = strMsg;
}
public String toString(){
return "类" + strExceptionConn + "未找到!\n" + strErrorMessage;
}
}
package com.mode.factory.daofactory.connection;
import java.sql.*;
/**
*所有DAO连接的父类,是一个抽象类
*/
public abstract class DAOConnection{
public abstract Connection getConnection();
}
package com.mode.factory.daofactory.connection;
import java.sql.*;
/**
*实现一个SQL的连接
*/
public class SQLConnection extends DAOConnection{
public Connection getConnection(){
Connection conn = null;
try{
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=bookshop","sa", "sa");
}catch(Exception e){
e.printStackTrace();
}
return conn;
}
}
package com.mode.factory.daofactory.connection;
import java.sql.*;
/**
*实现一个Oracle的连接
*/
public class OracleConnection extends DAOConnection{
public Connection getConnection(){
Connection conn = null;
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:accp","scott","tiger");
}catch(Exception e){
e.printStackTrace();
}
return conn;
}
}
package com.mode.factory.daofactory;
import com.mode.factory.daofactory.factory.DAOFactory;
import com.mode.factory.daofactory.exception.DAOException;
import java.sql.Connection;
/**
*一个测试类,将告诉你这个模式怎么使用
*/
public class DAOFactory_Test{
public static void main(String[] args){
Connection conn;
String dao = "com.mode.factory.daofactory.connection.SQLConnection";
//注意,这里dao我直接写了,这里完全可以写在XML文件里,然后每次更换和配置数据库的时候直接操作XML文件,这样就不用动任何类了。
//dao表示的就是我们获取Connection这个类的位置
try{
conn = DAOFactory.getConnection(dao);//用工厂的方式获得这个连接
}catch(DAOException daoe){
System.out.println(daoe.toString());
}
}
}