目录
前言
看到项目代码中有N多“If-else”,对于一个代码洁癖患者来说是非常不舒服的,同时我觉得写出优雅的代码是可以提升程序猿的工作满意度。这次我就把我以前的经验做一个汇总,以备后续参考。
丑陋的代码
Animal animal = new Animal();
if ("monkey".equals(animalType)){
animal.setFeet(2);
} else if ("pig".equals(animalType)){
animal.setFeet(4);
} else if ("fish".equals(animalType)){
animal.setFeet(1);
}
其实上面这种逻辑可以通过“键值对化”来解决。即以if条件作为key,把设置的值作为value。当然这种“键值对”化可以有很多种办法:
1、通过spring配置文件
/**
/** 1、把映射关系放到xml文件,然后通过spring加载;
/** 2、找到bean后通过animalType查找animalList对应的value进行设置。
/**
ApplicationContext ac = new FileSystemXmlApplicationContext(new String[]{"D:\\animal.xml"});
List<String, String> animalList = ac.getBean("animal");
Animal animal = new Animal();
animal.setFeet(animalList.get(animalType));
2、通过自定义枚举类
//* 首先定义一个枚举类,还是拿上面的丑陋代码做例子。
public enum AnimalFeetEnum {
FISH("FISH",1),MONKEY("MONKEY",2),PIG("PIG",4);
private String animal;
private int index;
public int getIndex() {
return index;
}
public String getAnimal() {
return feet;
}
private AnimalFeetEnum(String animal, int index){
this.index = index;
this.animal = animal;
}
AnimalFeetEnum getAnimalFeet(String animal) {
for (AnimalFeetEnum temp : AnimalFeetEnum.values()) {
if (animal.equals(temp.getAnimal())) {
return temp;
}
}
return null;
}
}
//* 设置动物的脚
Animal animal = new Animal("FISH");
animal.setFeet(AnimalFeetEnum.getAnimalFeet("FISH")); //* <-当然这里的“FISH”是表明是一个动态值,具体怎么传入看具体的上下文;
3、通过Optional类
有部分的if-else是来自于非空判断,以前我们的做法一般也是很low但也很无奈(无非写个StringUtils,然后通过isNull进行层层嵌套判断)。因为在JAVA8中引进了Optional,这样我们就可以直接通过Optional来解决。
//* 以前苦逼的生活是这样的:
private void printCardNum(User user){
String cardNum = user.getCardNum();
if (cardNum == null){
return;
}
System.out.println(cardNum);
}
//* 当有了Opional,原来生活可以是这么美好的
private void printCardNum(User user){
Optional<String> options = Optional.ofNullable(user.getCardNum());
options.isPresent(opt -> {
System.out.println(opt);
});
4、通过Map
这个相对简单,就是通过Map存储键值对,然后通过key获取value。不过,要保证以下方法取值正确是有前提的。相信各位老司机对HashMap也不陌生,HashMap是通过key的hash值作为地址进行链式存储的,如果hash值冲突的话最新值会覆盖旧有值。小心放完进去拿不出来,最稳妥的方式要不是重写hash()和equals();
public Consts{
//* 初始化动物脚的表
public static final HashMap animalMap = new HashMap();
animalMap.put("FISH",1);
animalMap.put("MONKEY",2);
animalMap.put("PIG",4);
....
}
//* 设置动物对象的“脚”属性
public Animal(){
@Autowired
private name;
@Autowired
private feet;
public void animal(String name){
this.name = name;
}
//* 从main方法看,通过Animal类的name属性作为key去animalMap获取相应的value
public static void main(String[] args){
Animal animal = new Animal("MONKEY");
animal.setFeet(Consts.animalMap.get(animal.getName()));
}
}
5、策略+工厂模式
首先,针对不同动物实现不同动物脚的逻辑,然后通过策略工厂的方法针对传入的动物类型实现动态绑定,这样更能体现JAVA作为OO的一种语言更加优美的处理,比纯粹的使用if-else这种类过程式语言优雅得多。
//* 设置动物接口
public interface IAnimal{
void setFeet();
}
//* 实现这几种动物
public class Monkey implements IAnimal{
public void setFeet(){
this.feet = 2;
}
}
public class PIG implements IAnimal{
public void setFeet(){
this.feet = 4;
}
}
public class FISH implements IAnimal{
public void setFeet(){
this.feet = 1;
}
}
//* 定义工厂类
public class AnimalFactory{
public static final HashMap<String, int> map = new HashMap<String, int>();
static{
map.put("FISH", FISH);
map.put("MONKEY", MONKEY);
map.put("PIG", PIG);
}
public IAnimal getAnimal(String type){
return map.get(type);
}
//* 通过main方法演示
public static void main(String[] args){
String type = "PIG";
IAnimal animal = AnimalFactory.getAnimal(type);
animal.setFeet();
}
}
结语
实际上,基友的智慧是强大的,消灭if-else也有各种各样的巧妙且优雅的方法。我的原则是,如果你只是通过不断的if-else去堆砌你的业务代码,然后你天天在说没有技术的提升,那别怪别人,因为真正的提升是需要靠自己去写代码的过程中去发现。这种的代码能力才是真正的内功,那些所谓的虾米虾米框架的就是一堆招式,招式会变的会过时的,等到云计算像spring一样渗透到方方面面的时候那些招式就一点用都没有,唯有内功才是可以恒久不变的。
*** 后面想到的或者在网上看到的比较有优雅的也继续收录在这里供自己赏读。