Bij*_* CD 9 java conditional-statements
有没有其他方法可以在Java中实现一个switch case,而不是看起来不好看的else.根据选择相应的方法,必须执行一组值组合.
Osc*_*Ryz 29
如果您的代码周围有大量的开关/案例陈述,它们会让您发疯.
您可以选择重构:使用多态替换条件.
假设您有一个用于将信息保存到不同设备的软件:定义了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;
}
Run Code Online (Sandbox Code Playgroud)
保存/删除/更新也是如此
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;
}
}
Run Code Online (Sandbox Code Playgroud)
等等....
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;
}
}
Run Code Online (Sandbox Code Playgroud)
使用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 );
}
Run Code Online (Sandbox Code Playgroud)
和不同的实现
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 ){
....
}
}
Run Code Online (Sandbox Code Playgroud)
其他类型将根据其逻辑实现.网络将处理套接字和流,DB将处理JDBC,ResultSets等XML与节点等.etc.
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
}
}
Run Code Online (Sandbox Code Playgroud)
最后,您只需委托调用.
后来:
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 );
}
}
Run Code Online (Sandbox Code Playgroud)
因此,您只需根据类型只为一次创建持久性管理器的正确实例.然后通过多态来解决所有调用.这是面向对象技术的关键特性之一.
如果您决定需要另一个持久性管理器,则只需创建新实现并分配给该类.
public WavePersistance implements PersistanceManager {
public void fetchData( Object criteria ) {
// ....
}
public void saveData( Object toSave ) {
// ....
}
public void deleteData( Object toDelete ){
// ....
}
public void updateData( Object toUpdate ){
// ....
}
}
Run Code Online (Sandbox Code Playgroud)
pto*_*mli 16
据推测,你正在努力解决案件不变的要求.通常这是代码味道,但有些事情你可以做.您可能想要提出并链接到另一个问题,详细说明您尝试切换的原因.
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);
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,您可能希望映射到"处理程序",例如
interface Handler {
public void doSomething();
}
Run Code Online (Sandbox Code Playgroud)
然后使这一切变为查找.
if (map.contains(key)) { map.get(key).doSomething(); }
Run Code Online (Sandbox Code Playgroud)
再次,这有点气味,所以请发一个说明推理的问题.
重构代码以使用多态可以摆脱对switch语句的需求。但是,切换有一些合法用途,因此这取决于您的情况。