Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

completed homework jv-DI #1000

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

completed homework jv-DI #1000

wants to merge 2 commits into from

Conversation

Oleg021
Copy link

@Oleg021 Oleg021 commented Sep 2, 2024

No description provided.

Copy link

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job on following the checklist and ensuring that all files meet the requirements! Your attention to detail is commendable, and the code looks clean and well-structured. Keep up the good work, and remember that small optimizations and informative exception messages can further enhance your code in the future. 👍 Keep coding and stay awesome! 🌟

✨ Please rate this review in the Platform's notification center. I will be grateful for your feedback! ✨

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Inject {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @Inject annotation is correctly defined with the @Retention policy set to RUNTIME. This is necessary for runtime reflection. No changes needed.

Comment on lines 20 to 21
} catch (Exception e) {
throw new RuntimeException("Error initializing injector", e);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to replace many exceptions that have a common parent with a general parental exception. In this case, you can catch ReflectiveOperationException instead of Exception to be more specific about what you are catching.

Comment on lines 41 to 43
} catch (NoSuchMethodException e) {
throw new RuntimeException("Could not find constructor for "
+ clazz.getName(), e);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When throwing an exception, add an informative message to it. Also, don't forget to add an exception you're catching in the catch block to the RuntimeException object you throw. This is implemented correctly here, but ensure to follow this pattern consistently.

Comment on lines 48 to 52
} catch (InstantiationException
| IllegalAccessException
| InvocationTargetException e) {
throw new RuntimeException("Could not instantiate "
+ clazz.getName(), e);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the previous comment, it is better to replace many exceptions that have a common parent with a general parental exception. In this case, ReflectiveOperationException can be used instead of listing all individual exceptions.

Comment on lines 70 to 72
if (dependency == null) {
throw new RuntimeException("No component found for: "
+ fieldType);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When throwing an exception, add an informative message to it. The message should include details about why the injection failed, such as missing @Component annotation on the class. This helps in debugging the issue.

Comment on lines 77 to 78
throw new RuntimeException("Not allowed to inject "
+ fieldType);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When throwing an exception, add an informative message to it. The message should include details about why the injection failed, such as missing @Component annotation on the class. This helps in debugging the issue.

Comment on lines 29 to 59
private void registerComponents() {
Class<?>[] classes = {
ProductServiceImpl.class,
ProductParserImpl.class,
FileReaderServiceImpl.class
};

for (Class<?> clazz : classes) {
if (clazz.isAnnotationPresent(Component.class)) {
Constructor<?> constructor;
try {
constructor = clazz.getDeclaredConstructor();
} catch (NoSuchMethodException e) {
throw new RuntimeException("Could not find constructor for "
+ clazz.getName(), e);
}
Object instance = null;
try {
instance = constructor.newInstance();
} catch (InstantiationException
| IllegalAccessException
| InvocationTargetException e) {
throw new RuntimeException("Could not instantiate "
+ clazz.getName(), e);
}
components.put(clazz, instance);
for (Class<?> element : clazz.getInterfaces()) {
components.put(element, instance);
}
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make Interface Implementations map a class field. You can fill it in using Map.of(). This will make the code cleaner and more maintainable.

public class Injector {
private static final Injector injector = new Injector();
private final Map<Class<?>, Object> components = new HashMap<>();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's check instances map before new instance creation. This ensures that you do not create a new instance if one already exists, which would be more efficient.

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add target

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add target

public class Injector {
private static final Injector injector = new Injector();
private final Map<Class<?>, Object> components = new HashMap<>();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private final Map<Class<?>, Object> components = new HashMap<>();
private final Map<Class<?>, Object> components = new HashMap<>();
private static final Map<Class<?>, Class<?>> interfaceImplementations;
static {
interfaceImplementations = Map.of(
FileReaderService.class, FileReaderServiceImpl.class,
ProductService.class, ProductServiceImpl.class,
ProductParser.class, ProductParserImpl.class);
}

Comment on lines 30 to 34
Class<?>[] classes = {
ProductServiceImpl.class,
ProductParserImpl.class,
FileReaderServiceImpl.class
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Class<?>[] classes = {
ProductServiceImpl.class,
ProductParserImpl.class,
FileReaderServiceImpl.class
};
Class<?> clazz = getImplementation(interfaceClazz);

where

private static Class<?> getImplementation(Class<?> interfaceClazz) {
        if (interfaceClazz.isInterface()) {
            return interfaceImplementations.get(interfaceClazz);
        }
        return interfaceClazz;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants