需求 : 输出结果一 :
晚会开始... 刘德华 演唱 `爱你一万年`! 少女团伙 跳 `性感广场舞`! 刘谦 表演 `大变死人`! 难忘今宵!
需求 : 输出结果二 :
晚会开始... 张学友 演唱 `一路上有你`! 少女时代 跳 `Gee Gee Gee`! 赵本山 表演 `卖拐`~ 难忘今宵!
分析 :
/* * 案例 : 举办晚会! * * 方式一 : 面向打印的思想. * 方式二 : Java 是面向对象的语言. 面向对象的编程思想. * 问题1 : 一旦 `对象` 进行更换, 凡是与对象相关的 `属性 & 方法` 都需要修正. 修正的代码非常大. * 解决方案 : 将对象共有的行为定义在 `接口中`. * * 问题2 : main 方法, 主业务逻辑, 希望来 `唱歌的, 跳舞的, 表演的`, 具体是哪个对象, 主业务逻辑不想管. * 解决方案 : 实现一个设计思想 `工厂设计模式`. PartyFactory 晚会工厂类, 作用: 创建晚会需要的具体对象. */
代码实现如下 :
主业务逻辑代码编写 :
public class EveningPartyDemo { public static void main(String[] args) throws Exception { System.out.println("晚会开始..."); Singable s = PartyFactory.getSingable(); s.sing(); Dancable d = PartyFactory.getDancable(); d.dance(); Performable p = PartyFactory.getPerformable(); p.perform(); System.out.println("难忘今宵!"); } }
工厂类设计 : 工厂设计模式讲解
// 工厂设计模式 : 配置文件 + 反射 public class PartyFactory { // 1. 创建一个 Properties 对象 private static Properties prop = new Properties(); // 问题 : 什么时候加载配置文件 ??? 配置文件只需要被加载一次. 并且必须在调用方法之前. // 静态代码块 : 1. 在类加载的同时被调用. 2.类加载在对象创建之前执行完毕. static { // 2. 使用 prop 对象调用 load 加载方法 try { prop.load(newFileReader("party.properties")); } catch (IOException e) { // 处理方案一 : 如果发生了异常, 就会输出异常信息. // e.printStackTrace(); // 处理方案二 : 手动再次抛出 throw new RuntimeException("文件加载失败!"); } } public static Singable getSingable() throws Exception { // 1. 从 prop 对象中获取信息 String className = prop.getProperty("singable"); // cn.itcast.eveningparty.ZhangXueYou // 2. 使用 Class 对象调用 forName 方法, 获取字符串在堆区中表示的 Class 对象 Class<?> cls = Class.forName(className); // 3. 创建一个字符串类表示的实例对象 Singable s = (Singable) cls.newInstance(); // 4. 返回反射创建的实例对象 return s; } public static Dancable getDancable() throws Exception { // 1. 从 prop 对象中获取信息 String className = prop.getProperty("dancable"); // cn.itcast.eveningparty.GirlsGeneration // 2. 使用 Class 对象调用 forName 方法, 获取字符串在堆区中表示的 Class 对象 Class<?> cls = Class.forName(className); // 3. 创建一个字符串类表示的实例对象 Dancable d = (Dancable) cls.newInstance(); // 4. 返回反射创建的实例对象 return d; } public static Performable getPerformable() throws Exception { // 1. 从 prop 对象中获取信息 String className = prop.getProperty("performable"); // cn.itcast.eveningparty.ZhaoBenShan // 2. 使用 Class 对象调用 forName 方法, 获取字符串在堆区中表示的 Class 对象 Class<?> cls = Class.forName(className); // 3. 创建一个字符串类表示的实例对象 Performable p = (Performable) cls.newInstance(); // 4. 返回反射创建的实例对象 return p; } }
配置文件信息如下: (配置文件存储于项目根目录下)
#singable=cn.itcast.eveningparty.ZhangXueYou #dancable=cn.itcast.eveningparty.GirlsGeneration #performable=cn.itcast.eveningparty.ZhaoBenShan singable=cn.itcast.eveningparty.LiuDeHua dancable=cn.itcast.eveningparty.GirlsTeam performable=cn.itcast.eveningparty.LiuQian
接口与实现类定义如下 : (Singable接口)
public interface Singable { void sing(); //public abstract }
public class ZhangXueYou implements Singable { @Override public voidsing() { System.out.println("张学友 演唱 `一路上有你`!"); } }
public class LiuDeHua implements Singable { @Override public voidsing() { System.out.println("刘德华 演唱 `爱你一万年`!"); } }
接口与实现类定义如下 : (Dancable接口)
public interface Dancable { void dance(); }
public class GirlsGeneration implements Dancable { @Override public voiddance() { System.out.println("少女时代 跳 `GeeGee Gee`!"); } }
public class GirlsTeam implements Dancable { @Override public voiddance() { System.out.println("少女团伙 跳 `性感广场舞`!"); } }
接口与实现类定义如下 : (Performable接口)
public interface Performable { void perform(); }
public class ZhaoBenShan implements Performable { @Override public voidperform() { System.out.println("赵本山 表演 `卖拐`!"); } }
public class LiuQian implements Performable { @Override public voidperform() { System.out.println("刘谦 表演 `大变死人`!"); } }
执行结果 : 只要修改配置文件,即可以改变程序的执行输出结果.
晚会开始... 刘德华 演唱 `爱你一万年`! 少女团伙 跳 `性感广场舞`! 刘谦 表演 `大变死人`! 难忘今宵!
晚会开始... 张学友 演唱 `一路上有你`! 少女时代 跳 `Gee Gee Gee`! 赵本山 表演 `卖拐`~ 难忘今宵!
|