工厂设计及好处:
有接口就立即想到工厂设计;
子类与父类耦合在一起,没有利用工厂模式,如果子类发生变化(添加或删除),
客户端即(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("没有发现这个类");
}
}
}