From 977d6f2ba7be15dcc566b986dce1285912f52e15 Mon Sep 17 00:00:00 2001 From: Andrei Punko Date: Mon, 11 Nov 2024 22:43:45 +0300 Subject: [PATCH] Adjust title of YT video in README, add +1 code-review material --- README.md | 2 +- materials/code-review-3.java | 58 ++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 materials/code-review-3.java diff --git a/README.md b/README.md index a84456e..d28957b 100644 --- a/README.md +++ b/README.md @@ -248,7 +248,7 @@ they contain enough code which describes implementation in a natural way. | Java интервью 10 | [Youtube](https://youtu.be/pcohe8zh314) | - | | Java интервью 11 | [Youtube](https://youtu.be/zufbVgdBCAI) | - | | Java интервью 12 | [Youtube](https://youtu.be/PD41epg_pT4) | - | -| Функциональные тесты Spring Boot сервиса с помощью Spock | [Youtube](https://youtu.be/GK5y3oA3qfM) | - | +| Функциональные тесты REST API с помощью Spock | [Youtube](https://youtu.be/GK5y3oA3qfM) | - | ## Materials & notes diff --git a/materials/code-review-3.java b/materials/code-review-3.java new file mode 100644 index 0000000..eddc129 --- /dev/null +++ b/materials/code-review-3.java @@ -0,0 +1,58 @@ +=== Ревью кода ==================== + +// Младший разработчик принес код нового сервиса на код ревью. +// Надо сделать ревью кода сервиса DataService и метода создания/получения новой сущности Data. +// Метод создания может вызваться из разных потоков и должен быть безопасен для такого режима использования. +// AccessService и DataRepository безопасны для использования из разных потоков. +// Предложить как можно сделать лучше и починить проблемы, если они есть. +@ReqArgsContructor +public class DataService { + + private AccessService access; // final, change name to `accessService` + private DataRepository repository; // final + private MessageDigest digest = get(); // should be removed, use Holder described below + + public DataService(AccessService access, DataRepository repository) { // could be deleted + this.access = access; + this.repository = repository; + } + + public Data get(String uid) { // change name to findByUid + access.checkRead(); // switch to use annotation-driven approach + return repository.get(uid); // switch to findByUid() method or another + } + + public void create(String name) { // return created object or creation status + access.checkWrite(); // switch to use annotation-driven approach + digest = get(); + repository.save(new Data( // add return + HexFormat.of().formatHex(digest.digest(name.getBytes())), // may be after switch to UUID - we could generate UUID by name OR use random UUID generation + name + )); + } + + public static MessageDigest get() { // move into some MessageDigestHolder, pre-create and get already created object. add synchronized at least + try { + return MessageDigest.getInstance("md5"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(); // pass e as RuntimeException parameter, add error logging if needed + } + } + + public record Data( // extract to separate class + String uid, // switch to use dedicated UUID class + String name + ) { + } + + // @Repository to wrap exceptions + public interface DataRepository { // extract to separate class + void save(Data data); + Data get(String uid); // change name to findByUid + } + + public interface AccessService { // extract to separate class + void checkRead(); + void checkWrite(); + } +}