重构包含多个 if 条件的代码
Refactoring code that contains multiple if conditions
这是我为保存 UrlEntity 编写的一些代码:
public UrlEntity saveUrlEntity(String longUrl, LocalDate dateAdded) {
int urlLength = longUrl.length();
if (urlLength >= Constants.MAX_LONG_URL_LENGTH) {
throw new LongUrlLengthExceededException("URL with length " + urlLength + " exceeds the max length of " + Constants.MAX_LONG_URL_LENGTH + " characters");
} else {
List<UrlEntity> urlEntity = urlRepository.findByLongUrl(longUrl);
if (urlEntity.size() > 0) {
return urlEntity.get(0);
} else {
final String shortUrl = urlShorten.shortenURL(longUrl);
if (urlRepository.findFirstByShortUrl(shortUrl).isPresent()) {
logger.error("A short short URL collision occured for long URL: " + longUrl + " with generated short URL" + shortUrl);
throw new ShortUrlCollisionException("A short URL collision occured");
} else {
logger.info("Shortened URL: " + shortUrl);
final UrlEntity urlEntityToSave = new UrlEntity(dateAdded, longUrl, shortUrl);
return urlRepository.save(urlEntityToSave);
}
}
}
}
以上代码存在于服务 class 中,看起来过于复杂。我正在尝试重构以便意图明确。这是我写的基本重构:
public UrlEntity saveUrlEntity(String longUrl, LocalDate dateAdded) {
int urlLength = longUrl.length();
if (urlLength >= Constants.MAX_LONG_URL_LENGTH) {
throw new LongUrlLengthExceededException("URL with length " + urlLength + " exceeds the max length of " + Constants.MAX_LONG_URL_LENGTH + " characters");
} else {
List<UrlEntity> urlEntity = urlRepository.findByLongUrl(longUrl);
if (urlEntity.size() > 0) {
return urlEntity.get(0);
} else {
return saveUrlEntityValue(longUrl, dateAdded);
}
}
}
private UrlEntity saveUrlEntityValue(String longUrl, LocalDate dateAdded){
final String shortUrl = urlShorten.shortenURL(longUrl);
if (urlRepository.findFirstByShortUrl(shortUrl).isPresent()) {
logger.error("A short short URL collision occured for long URL: " + longUrl + " with generated short URL" + shortUrl);
throw new ShortUrlCollisionException("A short URL collision occured");
} else {
logger.info("Shortened URL: " + shortUrl);
final UrlEntity urlEntityToSave = new UrlEntity(dateAdded, longUrl, shortUrl);
return urlRepository.save(urlEntityToSave);
}
}
这种重构并没有显着改进代码。是否有重构方法 saveUrlEntity
的代码模式或惯用方式?我正在使用 Java11
如果您使用 throw new
或 return
,则不需要 else 条件,因为该方法的结尾类似于
public UrlEntity saveUrlEntity(String longUrl, LocalDate dateAdded) {
int urlLength = longUrl.length();
if (urlLength >= Constants.MAX_LONG_URL_LENGTH) {
throw new LongUrlLengthExceededException("URL with length " + urlLength + " exceeds the max length of " + Constants.MAX_LONG_URL_LENGTH + " characters");
}
List<UrlEntity> urlEntity = urlRepository.findByLongUrl(longUrl);
if (urlEntity.size() > 0) {
return urlEntity.get(0);
}
final String shortUrl = urlShorten.shortenURL(longUrl);
if (urlRepository.findFirstByShortUrl(shortUrl).isPresent()) {
logger.error("A short short URL collision occured for long URL: " + longUrl + " with generated short URL" + shortUrl);
throw new ShortUrlCollisionException("A short URL collision occured");
}
logger.info("Shortened URL: " + shortUrl);
final UrlEntity urlEntityToSave = new UrlEntity(dateAdded, longUrl, shortUrl);
return urlRepository.save(urlEntityToSave);
}
这是非常主观的,但是...由于您的大多数 if
语句都是 guard/short-circuit 从句,即 throw
或 return
,因此没有必要使用 else
。我认为这个简单的更改使代码更具可读性。
public UrlEntity saveUrlEntity(String longUrl, LocalDate dateAdded) {
final int urlLength = longUrl.length();
if (urlLength >= Constants.MAX_LONG_URL_LENGTH) {
throw new LongUrlLengthExceededException("URL with length " + urlLength + " exceeds the max length of " + Constants.MAX_LONG_URL_LENGTH + " characters");
}
final List<UrlEntity> urlEntity = urlRepository.findByLongUrl(longUrl);
if (urlEntity.size() > 0) {
return urlEntity.get(0);
}
final String shortUrl = urlShorten.shortenURL(longUrl);
if (urlRepository.findFirstByShortUrl(shortUrl).isPresent()) {
logger.error("A short short URL collision occured for long URL: " + longUrl + " with generated short URL" + shortUrl);
throw new ShortUrlCollisionException("A short URL collision occured");
}
logger.info("Shortened URL: " + shortUrl);
final UrlEntity urlEntityToSave = new UrlEntity(dateAdded, longUrl, shortUrl);
return urlRepository.save(urlEntityToSave);
}
我还建议将 urlEntity.size() > 0
替换为 !urlEntity.isEmpty()
。
该方法似乎确实在做几件事,这违反了单一职责原则;你可能想考虑更好地打破它。
这是我为保存 UrlEntity 编写的一些代码:
public UrlEntity saveUrlEntity(String longUrl, LocalDate dateAdded) {
int urlLength = longUrl.length();
if (urlLength >= Constants.MAX_LONG_URL_LENGTH) {
throw new LongUrlLengthExceededException("URL with length " + urlLength + " exceeds the max length of " + Constants.MAX_LONG_URL_LENGTH + " characters");
} else {
List<UrlEntity> urlEntity = urlRepository.findByLongUrl(longUrl);
if (urlEntity.size() > 0) {
return urlEntity.get(0);
} else {
final String shortUrl = urlShorten.shortenURL(longUrl);
if (urlRepository.findFirstByShortUrl(shortUrl).isPresent()) {
logger.error("A short short URL collision occured for long URL: " + longUrl + " with generated short URL" + shortUrl);
throw new ShortUrlCollisionException("A short URL collision occured");
} else {
logger.info("Shortened URL: " + shortUrl);
final UrlEntity urlEntityToSave = new UrlEntity(dateAdded, longUrl, shortUrl);
return urlRepository.save(urlEntityToSave);
}
}
}
}
以上代码存在于服务 class 中,看起来过于复杂。我正在尝试重构以便意图明确。这是我写的基本重构:
public UrlEntity saveUrlEntity(String longUrl, LocalDate dateAdded) {
int urlLength = longUrl.length();
if (urlLength >= Constants.MAX_LONG_URL_LENGTH) {
throw new LongUrlLengthExceededException("URL with length " + urlLength + " exceeds the max length of " + Constants.MAX_LONG_URL_LENGTH + " characters");
} else {
List<UrlEntity> urlEntity = urlRepository.findByLongUrl(longUrl);
if (urlEntity.size() > 0) {
return urlEntity.get(0);
} else {
return saveUrlEntityValue(longUrl, dateAdded);
}
}
}
private UrlEntity saveUrlEntityValue(String longUrl, LocalDate dateAdded){
final String shortUrl = urlShorten.shortenURL(longUrl);
if (urlRepository.findFirstByShortUrl(shortUrl).isPresent()) {
logger.error("A short short URL collision occured for long URL: " + longUrl + " with generated short URL" + shortUrl);
throw new ShortUrlCollisionException("A short URL collision occured");
} else {
logger.info("Shortened URL: " + shortUrl);
final UrlEntity urlEntityToSave = new UrlEntity(dateAdded, longUrl, shortUrl);
return urlRepository.save(urlEntityToSave);
}
}
这种重构并没有显着改进代码。是否有重构方法 saveUrlEntity
的代码模式或惯用方式?我正在使用 Java11
如果您使用 throw new
或 return
,则不需要 else 条件,因为该方法的结尾类似于
public UrlEntity saveUrlEntity(String longUrl, LocalDate dateAdded) {
int urlLength = longUrl.length();
if (urlLength >= Constants.MAX_LONG_URL_LENGTH) {
throw new LongUrlLengthExceededException("URL with length " + urlLength + " exceeds the max length of " + Constants.MAX_LONG_URL_LENGTH + " characters");
}
List<UrlEntity> urlEntity = urlRepository.findByLongUrl(longUrl);
if (urlEntity.size() > 0) {
return urlEntity.get(0);
}
final String shortUrl = urlShorten.shortenURL(longUrl);
if (urlRepository.findFirstByShortUrl(shortUrl).isPresent()) {
logger.error("A short short URL collision occured for long URL: " + longUrl + " with generated short URL" + shortUrl);
throw new ShortUrlCollisionException("A short URL collision occured");
}
logger.info("Shortened URL: " + shortUrl);
final UrlEntity urlEntityToSave = new UrlEntity(dateAdded, longUrl, shortUrl);
return urlRepository.save(urlEntityToSave);
}
这是非常主观的,但是...由于您的大多数 if
语句都是 guard/short-circuit 从句,即 throw
或 return
,因此没有必要使用 else
。我认为这个简单的更改使代码更具可读性。
public UrlEntity saveUrlEntity(String longUrl, LocalDate dateAdded) {
final int urlLength = longUrl.length();
if (urlLength >= Constants.MAX_LONG_URL_LENGTH) {
throw new LongUrlLengthExceededException("URL with length " + urlLength + " exceeds the max length of " + Constants.MAX_LONG_URL_LENGTH + " characters");
}
final List<UrlEntity> urlEntity = urlRepository.findByLongUrl(longUrl);
if (urlEntity.size() > 0) {
return urlEntity.get(0);
}
final String shortUrl = urlShorten.shortenURL(longUrl);
if (urlRepository.findFirstByShortUrl(shortUrl).isPresent()) {
logger.error("A short short URL collision occured for long URL: " + longUrl + " with generated short URL" + shortUrl);
throw new ShortUrlCollisionException("A short URL collision occured");
}
logger.info("Shortened URL: " + shortUrl);
final UrlEntity urlEntityToSave = new UrlEntity(dateAdded, longUrl, shortUrl);
return urlRepository.save(urlEntityToSave);
}
我还建议将 urlEntity.size() > 0
替换为 !urlEntity.isEmpty()
。
该方法似乎确实在做几件事,这违反了单一职责原则;你可能想考虑更好地打破它。