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());
    }
   }
}

posted on 2007-08-20 16:09  kenty  阅读(774)  评论(0编辑  收藏  举报