版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
现在假设有一个晚会,规定了节目样式和节目顺序。下面写一段简单的代码:
@Test
public void demo1(){
System.out.println("晚会现在开始");
//周杰伦唱歌
new Jielun().sing();
//刘谦表演魔术
new Liuqian().magic();
//迈克尔杰克逊跳舞
new Michael().dance();
System.out.println("晚会结束");
}
这是用Java代码模拟的一场晚会,顺序就是唱歌、表演魔术、跳舞。
突然,周杰伦不能来了,这个时候就要改一个歌手。怎么改呢,就直接改就好了。
//new Jielun().sing();
//周杰伦不能来了,由陈奕迅来给大家演唱
new Eason().sing();
换来换去都还是歌手。这个时候我们就可以抽象出一个接口Singer
/**
* 歌手的接口,每个歌手都应实现这个接口
*/
interface Singer(){
void sing();
}
其它的也可以抽出接口
/**
* 魔术师的接口
*/
interface Magician{
void magic();
}
/**
* 跳舞的人的接口(不知道叫啥)
*/
interface Dancer{
void dance();
}
然后相应职业的人就实现相应的接口,然后代码就可以这样写:
@Test
public void demo1(){
System.out.println("晚会开始");
//省略了代码
Singer singer = new Jielun();
singer.sing();
}
这个时候,如果有歌手档期冲突,来不了了。就需要直接在demo1()中修改,这个时候我们可以使用工场模式。主代码中我们不做修改,利用歌手工程创建歌手对象。
/**
* 工场类
*/
public class Factory(){
/**
* 获取歌手
*/
public Singer getSinger(){
return new Jielun();
}
//后面两个也一样写
}
这个时候,主代码中就可以改成:
@Test
public void demo1(){
System.out.println("晚会开始了");
//这个时候,修改歌手时,不需要动主程序
Singer singer = Factory.getSinger();
singer.sing();
}
这个时候虽然不需要改主程序,但是工程类还是需要经常修改。这个时候我们可以利用配置文件part.properties(名字可以随便取,必须要.properties结尾):
Singer=com.zack.Jielun
Dancer=com.zack.Michael
Magician=com.zack.Liuqian
这里的键和接口名一致,值的话就是具体实现类的包全名。
那配置文件怎么用呢,这个时候就需要反射出场了:
/**
* 工程类中的获取歌手的方法
*/
public static Singer getSinger(){
//读取配置文件,party是配置文件名,不需要加后缀。Singer就是配置文件中的键
String className = ResourceBundle.getBundle("party").getString("Singer");
//利用包全名获取对象
try{
//调用className类的构造方法
Object obj = Class.forName(className).newInstance();
return (Singer)obj;
}catch(Exception e){
e.printStackTrace();
}
}
这样我们修改歌手的时候就不需要修改任何代码,只需修改配置文件就够了。