现在的位置: 首页 > 综合 > 正文

12—工厂模式

2013年10月16日 ⁄ 综合 ⁄ 共 7563字 ⁄ 字号 评论关闭

 

工厂设计及好处:
 有接口就立即想到工厂设计;
子类与父类耦合在一起,没有利用工厂模式,如果子类发生变化(添加或删除),
  客户端即(main)也要变;
  interface Fruit{
   //生长
   public void grow();
   //采摘
   public void pick();
   }
   
  class Apple implements Fruit{
   public void grow(){
    System.out.println("苹果在生长……");
    }
   public void pick(){
    System.out.println("在苹果……");
    }
   }
  class Orange implements Fruit{
   public void grow(){
    System.out.println("橘子在生长……");
    }
   public void pick(){
    System.out.println("在橘子……");
    }
   }
   
  public class Demo{
   public static void main(String args[]){
    Fruit f=new Apple();
    f.grow();
    f.pick();
    }
   }

1.利用工厂,如下:但是下面的工厂不能动态的返回所以子类中想要的某个实例
  interface Fruit{
   //生长
   public void grow();
   //采摘
   public void pick();
   }
   
  class Apple implements Fruit{
   public void grow(){
    System.out.println("苹果在生长……");
    }
   public void pick(){
    System.out.println("在苹果……");
    }
   }
  class Orange implements Fruit{
   public void grow(){
    System.out.println("橘子在生长……");
    }
   public void pick(){
    System.out.println("在橘子……");
    }
   }
   
  //创建一个工厂
  class Factory{
   public static Fruit getFruitInstance(){
    return new Orange();
    }
   }

  public class Demo{
   public static void main(String args[]){
    Fruit f=Factory.getFruitInstance();
    f.grow();
    f.pick();
    }
   }
2、下面的工厂模式实现了可以动态的返回所有子类中想要的某个实例:
  但是如果此时扩充了子类,则此时必须修改工厂;
  interface Fruit{
   //生长
   public void grow();
   //采摘
   public void pick();
   }
   
  class Apple implements Fruit{
   public void grow(){
    System.out.println("苹果在生长……");
    }
   public void pick(){
    System.out.println("在苹果……");
    }
   }
  class Orange implements Fruit{
   public void grow(){
    System.out.println("橘子在生长……");
    }
   public void pick(){
    System.out.println("在橘子……");
    }
   }
   
  //创建一个工厂
  class Factory{
   public static Fruit getFruitInstance(String type){
    Fruit f=null;
    if("Apple".equals(type)){
     f=new Apple();
     }
    if("Orange".equals(type)){
     f=new Orange();
     }  
    return f;
    }
   }

  public class Demo{
   public static void main(String args[]){
    if(args.length==0){
       System.out.println("必须输入名称:");
       System.exit(1);
       }
    Fruit f=Factory.getFruitInstance(args[0]);
    if(f!=null){
     f.grow();
     f.pick();
     }
    else{
     System.out.println("没有发现这个类");
     }
    }
   }
3、通过第三种实现去解决第二种实现中修改工厂的操作;
 但是在一个项目中可能有很多类实现了该接口,但是用户怎么知道具体有哪些子类呢?
 不知道有哪些子类,就无法传参数了(Apple、Orange、Cherry)
  package com.lid;
  interface Fruit{
   //生长
   public void grow();
   //采摘
   public void pick();
   }
   
  class Apple implements Fruit{
   public void grow(){
    System.out.println("苹果在生长……");
    }
   public void pick(){
    System.out.println("在苹果……");
    }
   }
  class Orange implements Fruit{
   public void grow(){
    System.out.println("橘子在生长……");
    }
   public void pick(){
    System.out.println("在橘子……");
    }
   }
  class Cherry implements Fruit{
   public void grow(){
    System.out.println("樱桃在生长……");
    }
   public void pick(){
    System.out.println("在樱桃……");
    }
   }
   
  //创建一个工厂
  class Factory{
   public static Fruit getFruitInstance(String type){
    Fruit f=null;
    //通过Class类完成
    try{
     f=(Fruit)Class.forName("com.lid."+type).newInstance();
     }
    catch(Exception e){
     System.out.println(e);
     }
    return f;
    }
   }

  public class Demo{
   public static void main(String args[]){
    if(args.length==0){
     System.out.println("必须输入名称:");
     System.exit(1);
     }
    Fruit f=Factory.getFruitInstance(args[0]);
    if(f!=null){
     f.grow();
     f.pick();
     }
    else{
     System.out.println("没有发现这个类");
     }
    }
   }

4、用下面的方式可以解决第三种实现的问题:
 用“代号”来代表“子类的包.类名称”(key--》value)map存的都是Object
  不可以,这是我们用Properties的setProperty
 要有一个文件列表,给用户列出全部的代码----》子类的映射;

  package com.lid;
  import java.util.*;
  import java.io.*;
  interface Fruit{
   //生长
   public void grow();
   //采摘
   public void pick();
   }
   
  class Apple implements Fruit{
   public void grow(){
    System.out.println("苹果在生长……");
    }
   public void pick(){
    System.out.println("在苹果……");
    }
   }
  class Orange implements Fruit{
   public void grow(){
    System.out.println("橘子在生长……");
    }
   public void pick(){
    System.out.println("在橘子……");
    }
   }
  class Cherry implements Fruit{
   public void grow(){
    System.out.println("樱桃在生长……");
    }
   public void pick(){
    System.out.println("在樱桃……");
    }
   }
   
  //创建一个工厂
  class Factory{
   public static Fruit getFruitInstance(String type){
    Fruit f=null;
    //通过Class类完成
    try{
     f=(Fruit)Class.forName(type).newInstance();
     }
    catch(Exception e){
     System.out.println(e);
     }
    return f;
    }
   }
  //定义一个新类,此类可以接受从键盘输入数据
  class InputData{
   BufferedReader buf=null;
   public InputData(){
    buf=new BufferedReader(new InputStreamReader(System.in));
    }
   public String getString(){
    String str=null;
    try{
     str=buf.readLine();
     }
    catch(Exception e){
     
     }
     return str;
    }
   }

  public class Demo{
   public static void main(String args[]){
    Properties p=new Properties();
    p.setProperty("a","com.lid.Apple");
    p.setProperty("b","com.lid.Orange");
    p.setProperty("c","com.lid.Cherry");
    System.out.println(p);
    //加入一个可以从键盘输入数据的类
    System.out.print("输入要使用的子类代号:");
    String code=new InputData().getString();
    
    Fruit f=Factory.getFruitInstance(p.getProperty(code));
    if(f!=null){
     f.grow();
     f.pick();
     }
    else{
     System.out.println("没有发现这个类");
     }
    }
   }

  以上代码还是不恰当,如果扩充了子类还得修改main中的:
   p.setProperty(String s,String m);

 解决的途径,通过文件保存Properties中的内容,以后修改文件即可,而不用修改类 :
  //保存到文件或从文件中读取的小例子
  package com.lid;
  import java.util.*;
  import java.io.*;

  public class test{
   public static void main(String args[]) throws Exception{
    Properties p=new Properties();
    /*p.setProperty("a","com.lid.Apple");
    p.setProperty("b","com.lid.Orange");
    p.setProperty("c","com.lid.Cherry");
    //在文件中保存一段数据,此数据为以上数据
    p.storeToXML(new FileOutputStream("property.xml"),"key-->value");*/
    
    //从文件中读取Properties中的属性
    p.loadFromXML(new FileInputStream("property.xml"));  
    System.out.println(p);
    }
   }
  
  一下为修改后的程序:
   package com.lid;
   import java.util.*;
   import java.io.*;
   interface Fruit{
    //生长
    public void grow();
    //采摘
    public void pick();
    }
    
   class Apple implements Fruit{
    public void grow(){
     System.out.println("苹果在生长……");
     }
    public void pick(){
     System.out.println("在苹果……");
     }
    }
   class Orange implements Fruit{
    public void grow(){
     System.out.println("橘子在生长……");
     }
    public void pick(){
     System.out.println("在橘子……");
     }
    }
   class Cherry implements Fruit{
    public void grow(){
     System.out.println("樱桃在生长……");
     }
    public void pick(){
     System.out.println("在樱桃……");
     }
    }
    
   //创建一个工厂
   class Factory{
    public static Fruit getFruitInstance(String type){
     Fruit f=null;
     //通过Class类完成
     try{
      f=(Fruit)Class.forName(type).newInstance();
      }
     catch(Exception e){
      System.out.println(e);
      }
     return f;
     }
    }
   //定义一个新类,此类可以接受从键盘输入数据
   class InputData{
    BufferedReader buf=null;
    public InputData(){
     buf=new BufferedReader(new InputStreamReader(System.in));
     }
    public String getString(){
     String str=null;
     try{
      str=buf.readLine();
      }
     catch(Exception e){
      
      }
      return str;
     }
    }
   class Init{
    public static Properties getPropertiesInit() throws Exception{
     Properties p=new Properties();
     p.loadFromXML(new FileInputStream("property.xml"));
     return p;
     }
    }
   public class Demo{
    public static void main(String args[]) throws Exception{
     Properties p=new Properties();
     p=Init.getPropertiesInit();
     System.out.println(p);
     //加入一个可以从键盘输入数据的类
     System.out.print("输入要使用的子类代号:");
     String code=new InputData().getString();
     
     Fruit f=Factory.getFruitInstance(p.getProperty(code));
     if(f!=null){
      f.grow();
      f.pick();
      }
     else{
      System.out.println("没有发现这个类");
      }
     }
    }

 

抱歉!评论已关闭.