Java 反射与工厂设计模式
程序员文章站
2022-04-07 18:03:45
文章目录案例: 编写一个传统的工厂类改进: 通过使用反射来完成处理对象的实例化改进: 使用泛型解决优化工厂设计曾经给过一个原则: 如果是你自己所编写的接口, 要想取得本接口的实例化对象, 最好使用工厂类来设计, 但是也需要知道传统工厂设计所带来的问题.案例: 编写一个传统的工厂类package com.cwq.beyond;interface IFruit{public void eat();}class Apple implements IFruit{@Overridep...
工厂设计曾经给过一个原则: 如果是你自己所编写的接口, 要想取得本接口的实例化对象, 最好使用工厂类来设计, 但是也需要知道传统工厂设计所带来的问题.
案例: 编写一个传统的工厂类
package com.cwq.beyond;
interface IFruit{
public void eat();
}
class Apple implements IFruit{
@Override
public void eat() {
System.out.println("[Apple]吃苹果.");
}
}
class Factory{
private Factory() {}
public static IFruit getInstance(String className) {
if ("apple".equals(className)) {
return new Apple();
}
return null;
}
}
public class TestDemo04 {
public static void main(String[] args) throws Exception {
IFruit fruit = Factory.getInstance("apple");
fruit.eat();
}
}
但是非常遗憾的是: 该工厂设计类在开发中根本就不可能使用, 因为在传统的工厂设计中, 当增加一个类的时候需要修改工厂类.
所以传统工厂类的最大弊端: 关键字 new
改进: 通过使用反射来完成处理对象的实例化
因为 Class 类可以使用 newInstance() 实例化对象, 同时 Class.forName() 能够接收 String 这个类名称.
package com.cwq.beyond;
interface IFruit {
public void eat();
}
class Apple implements IFruit {
@Override
public void eat() {
System.out.println("[Apple]吃苹果.");
}
}
class Cherry implements IFruit {
@Override
public void eat() {
System.out.println("[Cherry]吃樱桃.");
}
}
class Orange implements IFruit {
@Override
public void eat() {
System.out.println("[Orange]吃橘子.");
}
}
class Factory {
private Factory() {
}
public static IFruit getInstance(String className) {
IFruit fruit = null;
try {
fruit = (IFruit) Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return fruit;
}
}
public class TestDemo04 {
public static void main(String[] args) throws Exception {
IFruit fruit = Factory.getInstance("com.cwq.beyond.Apple");
IFruit fruit2 = Factory.getInstance("com.cwq.beyond.Orange");
IFruit fruit3 = Factory.getInstance("com.cwq.beyond.Cherry");
fruit.eat();
fruit2.eat();
fruit3.eat();
}
}
所以现在可以发现, 通过反射类改进的工厂设计模式, 其最大的特征在于可以方便动态进行子类的扩充操作, 而关键字new 会造成耦合问题.
但是以上的程序依然存在缺陷 : 如果所 ,现在有 10W 个接口, 那么按照此类模式就意味着需要有 10W 个工厂, 而10W 个工厂完成的都是相同的功能, 这样就很浪费了, 所以使用泛型来解决此问题.
改进: 使用泛型解决优化
package com.cwq.beyond;
interface IMessage{
public void print();
}
class MessageImpl implements IMessage{
@Override
public void print() {
System.out.println("com.cwq.beyond");
}
}
interface IFruit {
public void eat();
}
class Apple implements IFruit {
@Override
public void eat() {
System.out.println("[Apple]吃苹果.");
}
}
class Cherry implements IFruit {
@Override
public void eat() {
System.out.println("[Cherry]吃樱桃.");
}
}
class Orange implements IFruit {
@Override
public void eat() {
System.out.println("[Orange]吃橘子.");
}
}
class Factory {
private Factory() {
}
public static <T> T getInstance(String className) {
T t = null;
try {
t = (T) Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return t;
}
}
public class TestDemo04 {
public static void main(String[] args) throws Exception {
IFruit fruit = Factory.getInstance("com.cwq.beyond.Apple");
IFruit fruit2 = Factory.getInstance("com.cwq.beyond.Orange");
IFruit fruit3 = Factory.getInstance("com.cwq.beyond.Cherry");
fruit.eat();
fruit2.eat();
fruit3.eat();
IMessage msg = Factory.getInstance("com.cwq.beyond.MessageImpl");
msg.print();
}
}
从实际的开发来讲, 工厂类上使用泛型之后, 就可以为更多的类和接口进行服务了, 这应该是之后实际开发中要使用的工厂方式.
总结:
在实际开发之中, 如果可以掌握这种泛型和反射的组合操作原则, 那么对于整体的代码你就可以编写出高可用的程序了.
本文地址:https://blog.csdn.net/Beyond_Nothing/article/details/112051735