一 、工厂设计模式
需求 : 举办晚会.
开始 : 晚会开始了…
节目1 : 刘德华演唱 <冰雨> 歌曲 …
节目2 : 少女时代跳 <Gee Gee Gee> 舞曲 …
节目3 : 赵本山表演 <卖拐> 节目 …
结束 : 晚会太棒了, 难忘今宵…
实现一 : 面向打印编程
public class EveningParty {
public static void main(String[] args) {
System.out.println("开始 : 晚会开始了…");
System.out.println("节目1 : 刘德华演唱 <冰雨> 歌曲 …");
System.out.println("节目2 : 少女时代跳 <Gee Gee Gee> 舞曲 …");
System.out.println("节目3 : 赵本山表演 <卖拐> 节目 …");
System.out.println("结束 : 晚会太棒了, 难忘今宵…");
}
}
实现二 : 面向对象编程
准备数据:
LiuDeHua类
public class LiuDeHua {
public void sing() {
System.out.println("节目1 : 刘德华演唱 <冰雨> 歌曲 …");
}
}
GirlsGeneration类
public class GirlsGeneration {
public void dance() {
System.out.println("节目2 : 少女时代跳 <Gee Gee Gee> 舞曲 …");
}
}
ZhaoBenShan类
public class ZhaoBenShan {
public void perform() {
System.out.println("节目3 : 赵本山表演 <卖拐> 节目 …");
}
}
实现代码
public class EveningParty {
public static void main(String[] args) {
System.out.println("开始 : 晚会开始了…");
// 1. 创建一个 `刘德华` 对象
LiuDeHua liuDeHua = new LiuDeHua();
liuDeHua.sing();
// 2. 创建一个 `少女时代` 对象
GirlsGeneration girls = new GirlsGeneration();
girls.dance();
// 3. 创建一个 `赵本山` 对象
ZhaoBenShan zhaoBenShan = new ZhaoBenShan();
zhaoBenShan.perform();
System.out.println("结束 : 晚会太棒了, 难忘今宵…");
}
}
现在,刘德华通告满了来不了,怎么办?请张学友唱歌也可以啊。少女时代解散了不能来跳舞了,怎么办?我请少女团伙过来。本山大叔不来演小品了,我请刘谦来变魔术吧。
ZhangXueYou类
public class ZhangXueYou {
public void sing() {
System.out.println("节目1 : 张学友演唱 <一路上有你> 歌曲...");
}
}
GirlsTeam类
public class GirlsTeam {
public void dance() {
System.out.println("节目2 : 少女团伙跳 <京东不太热> 舞曲...");
}
}
LiuQian类
public class LiuQian {
public void perform() {
System.out.println("节目3 : 刘谦表演 <大变死人> 节目...");
}
}
代码实现
public class EveningParty {
public static void main(String[] args) {
System.out.println("开始 : 晚会开始了…");
// 1. 创建一个 `张学友` 对象
ZhangXueYou zhangXueYou = new ZhangXueYou();
zhangXueYou.sing();
// 2. 创建一个 `少女时代` 对象
GirlsTeam girls = new GirlsTeam();
girls.dance();
// 3. 创建一个 `刘谦` 对象
LiuQian liuQian = new LiuQian();
liuQian.perform();
System.out.println("结束 : 晚会太棒了, 难忘今宵…");
}
}
实现三 : 面向接口编程
我们发现了,需求是举办舞会,表演节目是谁我不管,只要晚会举行了就好。
要唱歌的就来一个唱歌的、要跳舞的就来一个跳舞的、要表演的就来一个会表演的就行。
所以我们可以让对象实现接口来继续。
需求 : 举办晚会.
开始 : 晚会开始了…
节目1 : 刘德华演唱 <冰雨> 歌曲 … 找一个唱歌的.
节目2 : 少女时代跳 <Gee Gee Gee> 舞曲 … 找一个跳舞的.
节目3 : 赵本山表演 <卖拐> 节目 … 找一个表演的.
结束 : 晚会太棒了, 难忘今宵…
Singable 接口
public interface Singable {
void sing();
}
Dancable 接口
public interface Dancable {
void dance();
}
Performable 接口
public interface Performable {
void perform();
}
让LiuDeHua、ZhangXueYou实现Singable 接口;
public class LiuDeHua implements Singable {
@Override
public void sing() {
System.out.println("节目1 : 刘德华演唱 <冰雨> 歌曲 …");
}
}
public class ZhangXueYou implements Singable {
@Override
public void sing() {
System.out.println("节目1 : 张学友演唱 <一路上有你> 歌曲...");
}
}
GirlsGeneration、GirlsTeam实现 Dancable 接口
public class GirlsGeneration implements Dancable {
@Override
public void dance() {
System.out.println("节目2 : 少女时代跳 <Gee Gee Gee> 舞曲 …");
}
}
public class GirlsTeam implements Dancable {
@Override
public void dance() {
System.out.println("节目2 : 少女团伙跳 <京东不太热> 舞曲...");
}
}
ZhaoBenShan、LiuQian实现 Performable 接口
public class ZhaoBenShan implements Performable {
@Override
public void perform() {
System.out.println("节目3 : 赵本山表演 <卖拐> 节目 …");
}
}
public class LiuQian implements Performable {
@Override
public void perform() {
System.out.println("节目3 : 刘谦表演 <大变死人> 节目...");
}
}
实现代码:
public class EveningParty {
public static void main(String[] args) {
System.out.println("开始 : 晚会开始了…");
// 1. 创建一个 `张学友` 对象
Singable s = new ZhangXueYou();
s.sing();
// 2. 创建一个 `少女团伙` 对象
Dancable d = new GirlsTeam();
d.dance();
// 3. 创建一个 `刘谦` 对象
Performable p = new LiuQian();
p.perform();
System.out.println("结束 : 晚会太棒了, 难忘今宵…");
}
}
public class EveningParty {
public static void main(String[] args) {
System.out.println("开始 : 晚会开始了…");
// 1. 创建一个 `刘德华` 对象
Singable s = new LiuDeHua();
s.sing();
// 2. 创建一个 `少女时代` 对象
Dancable d = new GirlsGeneration();
d.dance();
// 3. 创建一个 `赵本山` 对象
Performable p = new ZhaoBenShan();
p.perform();
System.out.println("结束 : 晚会太棒了, 难忘今宵…");
}
}
实现四 : 工厂设计模式编程
换人的流程好像变简单了。
但是,我的主业务逻辑是举办晚会, 到底来谁, 不重要. 那么为什么每次换人时, 我的主业务逻辑都需要不停修改呢 ???。
我们应该将晚会需要的 对象
交给一个独立的类提供. 这个类就被称为 晚会工厂类
. PartyFactory. 作用: 为主业务逻辑提供需要的对象.
这样就实现了,我的主业务逻辑不变,需要的对象由晚会的工厂类来实现。
// 工厂设计模式 : 配置文件 + 反射
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
public class PartyFactory {
// 属性
private static final Properties prop;
// 静态代码块
static {
prop = new Properties();
try {
prop.load(new FileReader("party.properties"));
} catch (IOException e) {
throw new RuntimeException("配置文件加载失败!");
}
}
public static Singable getSingable() {
// 1. 根据 key 获取 prop 对象中的 value
String className = prop.getProperty("Singable");
try {
// 2. 反射创建对象
Class<?> cls = Class.forName(className);
Object o = cls.getDeclaredConstructor().newInstance();
// 3. 强转, 并返回
return (Singable) o;
} catch (Exception e) {
throw new RuntimeException("对象创建失败!");
}
}
public static Dancable getDancable() {
// 1. 根据 key 获取 prop 对象中的 value
String className = prop.getProperty("Dancable");
try {
// 2. 反射创建对象
Class<?> cls = Class.forName(className);
Object o = cls.getDeclaredConstructor().newInstance();
// 3. 强转, 并返回
return (Dancable) o;
} catch (Exception e) {
throw new RuntimeException("对象创建失败!");
}
}
public static Performable getPerformable() {
// 1. 根据 key 获取 prop 对象中的 value
String className = prop.getProperty("Performable");
try {
// 2. 反射创建对象
Class<?> cls = Class.forName(className);
Object o = cls.getDeclaredConstructor().newInstance();
// 3. 强转, 并返回
return (Performable) o;
} catch (Exception e) {
throw new RuntimeException("对象创建失败!");
}
}
}
配置文件 : party.properties
#Singable=cn.itcast.party.LiuDeHua
#Dancable=cn.itcast.party.GirlsGeneration
#Performable=cn.itcast.party.ZhaoBenShan
Singable=cn.itcast.party.ZhangXueYou
Dancable=cn.itcast.party.GirlsTeam
Performable=cn.itcast.party.LiuQian
实现代码:
public class EveningParty {
public static void main(String[] args) {
System.out.println("开始 : 晚会开始了…");
// 1. 晚会工厂类, 给我来一个会唱歌的.
Singable s = PartyFactory.getSingable();
s.sing();
// 2. 晚会工厂类, 给我来一个会跳舞的.
Dancable d = PartyFactory.getDancable();
d.dance();
// 3. 晚会工厂类, 给我来一个会表演的.
Performable p = PartyFactory.getPerformable();
p.perform();
System.out.println("结束 : 晚会太棒了, 难忘今宵…");
}
}
party.properties就像是晚会表演名单一样,我只管提需求,而真正干活的是承办者也就是晚会工厂类
,我不管你给我什么,我只要晚会能顺利举行就好,这就是设计过程中的 Factorty 设计模式。
实现五 : 工厂设计编程优化方案
// 工厂设计模式 : 配置文件 + 反射
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
public class PartyFactory {
// 属性
private static final Properties prop;
// 静态代码块
static {
prop = new Properties();
try {
prop.load(new FileReader("party.properties"));
} catch (IOException e) {
throw new RuntimeException("配置文件加载失败!");
}
}
public static <T> T getInstance(Class<T> cls) {
// 0. 获取 key
String key = cls.getSimpleName();
// 1. 根据 key 获取 prop 对象中的 value
String className = prop.getProperty(key);
try {
// 2. 反射创建对象
Class<?> c = Class.forName(className);
Object o = c.getDeclaredConstructor().newInstance();
// 3. 强转, 并返回
return (T) o;
} catch (Exception e) {
throw new RuntimeException("对象创建失败!");
}
}
}
通过反射将代码设计的更加简洁。
配置文件 : party.properties
#Singable=cn.itcast.party.LiuDeHua
#Dancable=cn.itcast.party.GirlsGeneration
#Performable=cn.itcast.party.ZhaoBenShan
Singable=cn.itcast.party.ZhangXueYou
Dancable=cn.itcast.party.GirlsTeam
Performable=cn.itcast.party.LiuQian
实现代码:
public class EveningParty {
public static void main(String[] args) {
System.out.println("开始 : 晚会开始了…");
// 1. 晚会工厂类, 给我来一个会唱歌的.
Singable s = PartyFactory.getSingable();
s.sing();
// 2. 晚会工厂类, 给我来一个会跳舞的.
Dancable d = PartyFactory.getDancable();
d.dance();
// 3. 晚会工厂类, 给我来一个会表演的.
Performable p = PartyFactory.getPerformable();
p.perform();
System.out.println("结束 : 晚会太棒了, 难忘今宵…");
}
}
运行程序,结果都是下面两种的一种,但是不管哪一种都实现了我举办晚会的需求。
结果1:
结果2:
工厂设计模式总结
工厂设计模式是一种强调结果而不在乎过程的设计模式。