Java 中切换大小写的替代方案
2022-09-04 23:45:09
有没有其他方法可以在Java中实现开关案例,除了其他看起来不好。一组值将在那里组合,根据选择必须执行相应的方法。
有没有其他方法可以在Java中实现开关案例,除了其他看起来不好。一组值将在那里组合,根据选择必须执行相应的方法。
如果你的代码周围有很多开关/案例语句,它们会让你发疯。
您可以选择重构:用多态性替换条件。
假设您有一个用于将信息保存到不同设备的软件:定义了4个持久性操作:获取,保存,删除,更新,这可以通过N个持久性机制(平面文件,网络,RDBMS,XML等)来实现。
你的代码必须支持它们,所以在4个不同的地方你有这个:
以前
class YourProblematicClass {
....
public void fetchData( Object criteria ) {
switch ( this.persitanceType ) {
case FilePersistance:
// open file
// read it
// find the criteria
// build the data
// close it.
break;
case NetWorkPersistance:
// Connect to the server
// Authenticate
// retrieve the data
// build the data
// close connection
break;
case DataBasePersistace:
// Get a jdbc connection
// create the query
// execute the query
// fetch and build data
// close connection
break;
}
return data;
}
保存/删除/更新相同
public void saveData( Object data) {
switch ( this.persitanceType ) {
case FilePersistance:
// open file, go to EOF, write etc.
break;
case NetWorkPersistance:
// Connect to the server
// Authenticate
// etc
break;
case DataBasePersistace:
// Get a jdbc connection, query, execute...
break;
}
}
等等....
public void deleteData( Object data) {
switch ( this.persitanceType ) {
case FilePersistance:
break;
case NetWorkPersistance:
break;
case DataBasePersistace:
break;
}
}
public void updateData( Object data) {
switch ( this.persitanceType ) {
case FilePersistance:
break;
case NetWorkPersistance:
break;
case DataBasePersistace:
break;
}
}
使用 switch/case 语句变得有问题:
每次要添加新类型时,都必须在每个部分中插入新的开关/机箱。
很多时候,有些类型是相似的,它们不需要不同的开关/外壳(你可以级联它们)
其他一些是,有时它们略有不同
您甚至可能需要在运行时加载不同类型的类型(如插件)
因此,这里的重构是添加一个接口或抽象类型,并让不同的类型实现该接口并将责任委托给该对象。
所以你会有这样的东西:
后
public interface PersistenceManager {
public void fetchData( Object criteria );
public void saveData( Object toSave );
public void deleteData( Object toDelete );
public void updateData( Object toUpdate );
}
和不同的实现
public class FilePersistence implements PersistanceManager {
public void fetchData( Object criteria ) {
// open file
// read it
// find the criteria
// build the data
// close it.
}
public void saveData( Object toSave ) {
// open file, go to EOF etc.
}
public void deleteData( Object toDelete ){
....
}
public void updateData( Object toUpdate ){
....
}
}
其他类型将根据其逻辑实现。网络将处理套接字和流,DB将处理JDBC,ResultSets等。XML 与节点等。
public class NetworkPersistence implements PersistanceManager {
public void fetchData( Object criteria ) {
// Socket stuff
}
public void saveData( Object toSave ) {
// Socket stuff
}
public void deleteData( Object toDelete ){
// Socket stuff
}
public void updateData( Object toUpdate ){
// Socket stuff
}
}
public class DataBasePersistence implements PersistanceManager {
public void fetchData( Object criteria ) {
// JDBC stuff
}
public void saveData( Object toSave ) {
// JDBC stuff
}
public void deleteData( Object toDelete ){
// JDBC stuff
}
public void updateData( Object toUpdate ){
// JDBC stuff
}
}
最后,您只需要委派调用即可。
后:
public YouProblematicClass { // not longer that problematic
PersistamceManager persistance = // initialize with the right one.
public void fetchData( Object criteria ) {
// remove the switch and replace it with:
this.persistance.fetchData( criteria );
}
public void saveData( Object toSave ) {
// switch removed
this.persistance.saveData( toSave );
}
public void deleteData( Object toDelete ){
this.persistance.deleteData( toDelete );
}
public void updateData( Object toUpdate ){
this.persistance.updateData( toUpdate );
}
}
因此,您只需要根据类型为持久性管理器创建正确的实例一次。然后,所有调用都通过多态性解析。这是面向对象技术的关键特征之一。
如果您决定需要另一个持久性管理器,只需创建新的实现并分配给该类即可。
public WavePersistance implements PersistanceManager {
public void fetchData( Object criteria ) {
// ....
}
public void saveData( Object toSave ) {
// ....
}
public void deleteData( Object toDelete ){
// ....
}
public void updateData( Object toUpdate ){
// ....
}
}
想必您正在为案例恒定的要求而苦苦挣扎。通常,这是一种代码异味,但您可以执行一些操作。您可能希望提出并链接到另一个问题,该问题详细说明了您尝试切换的原因。
Map<String,Object> map = new HasMap<String,Object>();
// ... insert stuff into map
// eg: map.add("something", new MyObject());
String key = "something";
if (map.contains(key)) {
Object o = map.get(key);
}
在上面的示例中,您可能希望映射到“处理程序”,如下所示
interface Handler {
public void doSomething();
}
然后,这一切都变成了一个查找。
if (map.contains(key)) { map.get(key).doSomething(); }
同样,这有点异味,所以请发布一个说明推理的问题。