While writing a simple skills system for a game, I have run into a small hiccup. My basic convention for my system uses annotations to define if a skill or ability meets all predefined requirements, but I want it to be extendable.
To do this I have implemented an Enum class with an interface and Annotated the Enums within to gather basic information. I have found that this limits my ability to create another annotation that can be placed on other classes to see if that skill needs to be "trained".
Something like:
public enum AthleticSkills implements AnnotatedSkill {
#Skill(name = "Jump", base = Agility.class, trained = true)
JUMP(public void use(){})
}
This enum could be any number of skill types, such as StrengthSkills, etc, all interfacing AnnotatedSkill, which does let me define the type of AnnoatedSkill within methods and parameters, but I wanted to do something similar to:
public #interface TrainedSkill {
AnnotatedSkill[] value();
}
Trained skills are kept in a Set<AnnotatedSkill>.
I know this isn't possible, but I wanted to stick with the convention I have setup. I am willing to redefine how I setup skills if necessary, but if anyone has any way to make this work to keep it similar to this, I would be most greatful.
Some more explanation of how this is used:
Skills are simple, everyone will have them (think old DND skills) and everyone can use them, they use the class (Agility.class, Strength.class, etc) which are stat classes to adjust their effectiveness. Along with this there is the ability to train in a skill, a one shot, you know it or not, this is added to Set<AnnotatedSkill> within the player object, this just means you get additional modifiers when you use the skill.
The use() method within the ENUM can be used based on whether the trained modifier in the annotation is set, if true, it can only be used if skill is trained, if false, anyone can use it.
There is also another Annotation that can be added if you wish to limit who can train the skill (#Requirements) which can limit the training/using to classes/races/etc
I assume this would fall more into a Framework for skills/classes/races/etc.
Assume the following:
#Types(types = {EffectTypes.BUFF, EffectTypes.HEALTH, EffectTypes.HEAL})
#Requirements(
abilities = {
#RequireAbility(required = TimedHealAbility.class)})
#TrainedSkill(AthleticSkills.JUMP)
public class TimedHealEffect extends EffectComponent {}
This effect will only happen is they have trained AthleticSkills.JUMP, as well if they meet the requirements from #requirements.
Tracking Trained skills:
public class SkillTracking {
private Set<AnnotatedSkill> trainedSkills = Collections.newSetFromMap(new ConcurrentHashMap<AnnotatedSkill, Boolean>());
public void addSkill(AnnotatedSkill skill) {
trainedSkills.add(skill);
}
public boolean removeSkill(AnnotatedSkill skill) {
return trainedSkills.remove(skill);
}
public boolean hasSkill(AnnotatedSkill skill) {
return trainedSkills.contains(skill);
}
}
Related
I am going through dozen tutorials which prove to me of very little help because production code is not an animal, bird or human. Not a weapon of type cutting or shooting it is much more complex to reason about.
So returning to reality, scenario:
service 1 is exchanging messages with service 2 through Kafka, messages are serialized/deserialized with Jackson, the model class is shared between services as jar.
Now the plague part, the culmination of evil :
#JsonTypeInfo(
use = Id.NAME,
property = "type",
visible = true
)
#JsonSubTypes({#Type(
value = InternalTextContent.class,
name = "text"
), #Type(
value = InternalImageContent.class,
name = "image"
), #Type(
value = InternalAudioContent.class,
name = "audio"
), #Type(
value = InternalCustomContent.class,
name = "custom"
)})
public abstract class InternalContent {
#JsonIgnore
private ContentType type;
public InternalContent() {
}
Obviously when the time will come to work with this content we will have something like:
message.getInternalContent
which results to a sea of switch statements, if conditions, instanceof and wait for it ... downcasting everywhere
And this is just one property example the wrapping object contains. Clearly I cannot add polymorphic behaviour to InternalContent , because hellooo it is within a jar.
What went wrong here? Is it even wrong?
How do I add polymorphic behaviour ? To add a new mitigating layer, I still need instanceof in some factory to create a new type of polymorphic objects family which are editable to add the desired behavior? Not even sure it is going to be better, it just smells and make me want to shoot the advocates which throw blind statement like instanceof with downcasting is a code smell" torturing people like me who genuinely care, which makes me wonder if they ever worked on a real project. I deliberately added system environment details to understand how to model not just the code but interaction between systems. What are possible redesign options to achieve the "by book" solution?
So far I can think of that sharing domain model is a sin. But then if I use different self-service-contained classes to represent same things for serialization/deserialization I gather flexibility but lose contract and increase unpredictability. Which is what technically happens with HTTP contracts.
Should I send different types of messages with different structures along the wire instead of trying to fit common parts and subtypes for uncommon in a single message type?
To throw more sand at OO , I consider Pivotal the best among the best yet:
https://github.com/spring-projects/spring-security/blob/master/core/src/main/java/org/springframework/security/authentication/dao/AbstractUserDetailsAuthenticationProvider.java
public boolean supports(Class<?> authentication) {
return (UsernamePasswordAuthenticationToken.class
.isAssignableFrom(authentication));
}
AuhenticationManager has a list of AuthenticationProviders like this and selects correct one based on the method above. Does this violate polymorphism ? Sometimes it all just feels as a hype...
Use the visitor pattern.
Example (I'll limit to two subclasses, but you should get the idea):
interface InternalContentVisitor<T> {
T visitText(InternalTextContent c);
T visitImage(InternalImageContent c);
}
public abstract class InternalContent {
public abstract <T> T accept(InternalContentVisitor<T> visitor);
// ...
}
public class InternalTextContent {
#Override
public <T> T accept(InternalContentVisitor<T> visitor) {
return visitor.visitText(this);
}
}
public class InternalImageContent {
#Override
public <T> T accept(InternalContentVisitor<T> visitor) {
return visitor.visitImage(this);
}
}
This code is completely generic, and can be shared by any application using the classes.
So now, if you want to polymorphically do something in project1 with an InternalContent, all you need to do is to create a visitor. This visitor is out of the InternalContent classes, and can thus contain code that is specific to project1. Suppose for example that project1 has a class Copier that can be used to create a Copy of a text or of an image, you can use
InternalContent content = ...; // you don't know the actual type
Copier copier = new Copier();
Copy copy = content.accept(new InternalContentVisitor<Copy>() {
#Override
public Copy visitText(InternalTextContent c) {
return copier.copyText(c.getText());
}
#Override
public Copy visitImage(InternalImageContent c) {
return copier.copyImage(c.getImage());
}
});
So, as you can see, there is no need for a switch case. Everything is still done in a polymorphic way, even though the InternalContent class and its subclasses have no dependency at all on the Copier class that only exists in project1.
And if a new InternalSoundContent class appears, all you have to do is to add a visitSound() method in the visitor interface, and implement it in all the implementations of this interface.
Currently, I try to design some things with OO principles in mind. So let's say, before processing user input, I need to validate it. According to OO, a separate Validator class would be the correct way. This would look as follows:
public class Validator{
public void validate(String input) throws ValidationException{
if (input.equals("")) throw new ValidationException("Input was empty");
}
}
Then, my processing class, which got the validator object before via dependency injection would call validator.validate(input)
A good point about this design is, that
My processing class can get a mock for the validator via DI which makes testing easier
The Validator class can be tested independently
However, my doubts are in the design of the Validator. According to OO, it misses some kind of state. With this design, it is as util class and the validate method could be static. And I read a lot of times that (static) Util classes are bad OO design. So, how can this be done with more OO while keeping the two advantages I mentioned?
PS.: Maybe, OO is simply a bad solution for this kind of problem. However, I would like to see how the OO solution would look like and form my own opinion.
The validator in your example doesn't have a state (and doesn't need any), but another validator could require one (say with a format):
Example:
public class RegExValidator {
private Pattern pattern;
public RegExValidator(String re) {
pattern = Pattern.compile(re);
}
public void validate(String input) throws ValidationException {
if (!pattern.matcher(input).matches()) {
throw new ValidationException("Invalid syntax [" + input + "]");
}
}
}
Concentrating on the OOP aspect of your question (rather than the question if an Exception is the correct way to handle your validation):
Why have a single validator?
interface Validator<T> {
void validate(T toValidate) throws ValidationException;
}
would enable you to write classes that can validate any class T and be very testable. Your validator would look like this:
class EmptyStringValidator implements Validator<String> {
public void validate(String toValidate) {
if(toValidate == null || toValidate.isEmpty()) throw new ValidationException("empty!!!");
}
}
and you could test it very easily.
In fact, if you're using Java 8, this would be a functional interface, so a single utility class could host several validators:
class ValidationUtil {
public static void emptyString(String val) // same code as above
}
and ValidationUtil::emptyString would implement Validator<String>.
You would combine several validators with a composite pattern.
You could also have a validator with a state if that's what you need...
class ListIsSortedValidator implements Validator<Integer> {
private int lastInt = Integer.MIN_VALUE;
public void validate(Integer val) throw ValidationException {
if (val < lastInt) throw new ValidationException("not sorted");
lastInt = val;
}
}
That you could use to for instance validate a list:
List<Integer> list = createList();
Validator<Integer> validator = new ListIsSortedValidator();
list.forEach(validator::validate);
It depends on the circumstances of course, but I think your instinct is correct. This design could be more Object-Oriented.
It is not just that Validator has no state, which is a purely mechanical indicator that it is likely not a correct abstraction, but the name itself tells us something. Usually Validator (or even EmptyStringValidator) is not part of the problem domain. It is always a bad sign when you have to create something purely technical (although sometimes it is the less of two evils).
I assume you are not writing a web-framework, you are trying to write an application that has some domain. For example it has user registration. Then, RegistrationForm is part of the problem domain. Users know about the "registration form", you can talk about it and they will know what you mean.
In this case, an Object-Oriented solution for validation would be that this object is responsible for the validation of itself during the "submitting" of itself.
public final class RegistrationForm extends Form {
...
#Override
public void submit() {
// Do validation here
// Set input fields to error if there are problems
// If everything ok do logic
}
}
I know this is not the solution normally seen or even supported by web-frameworks. But it is how an Object-Oriented solution would look like.
The two important points to always keep in mind are:
Don't "get" data from objects, ask them to do something instead. This is as applicable to UI code as anything else.
OO makes sense when the objects focus on meaningful things, i.e. the problem domain. Avoid over-representing technical (unimportant) objects, like Validator (if that's not your application's domain).
Background
I want to realize dependency injection in Python using injector (or pinject) which itself heavily borrows from guice. While an answer using Python/injector would be ideal, I'm also very happy about solutions/approaches that feature Java/guice.
Intention
I'll give you a quick summary of what I want to achieve: I have a component that depends on a list/sequence of other components that all implement the same interface. Those components have dependencies themselves which may vary amongst the different implementations. The concrete types (implementations) shall be configurable by the user (or using any mechanism of the DI framework).
Example
Yes, I've read Modules should be fast and side-effect free which suggests not to use an XML file for configuration, however as I don't know how to realize this within the framework I'll use one to demonstrate the dependency structure:
<RentingAgency>
<Vehicles>
<Car>
<DieselEngine></DieselEngine>
</Car>
<Car>
<PetrolEngine></PetrolEngine>
</Car>
<Bike></Bike>
</Vehicles>
</RentingAgency>
In this example there is a renting agency (the component that depends on a list of others) that rents out all kinds of vehicles (the interface). The specific vehicles in their fleet (in this case two cars and one bike) should be configurable but fixed during runtime. The vehicles themselves can have dependencies and they can be different depending on the type of vehicle (a car depends on a motor, a bike has no dependencies in this case).
Question
How can I construct the renting agency within the DI framework so that all required vehicles are injected and their dependencies resolved properly?
Maybe helpful
Multibinder
I've read about Multibinder (injector seems to have something similar with Binder.multibind) which allows for injecting a collection of objects that implement the same interface. However:
Can it be used to create multiple instances of the same class that need to receive different dependencies (the two cars (Class Car) in the example have different motors: Interface Motor, Class DieselEngine, class PetrolEngine)?
Using providers to accomplish that task seems to me like giving up the benefits of dependency injection: I could manually create the Car instances in the provider, passing the required Motor as argument, however because this pattern repeats further down the chain (i.e. multiple Motors of the same type are used and they also have dependencies) I want to use dependency injection for generating those objects too. But to manually use them in the provider it seems to me like I have to obtain the instances directly from the injector. The docs mention that injecting the injector is a rare case and from my understanding of dependency injection, the great benefit is that one can request a component and all dependencies are resolved by the framework automatically.
Also because I actually use Python I'm not sure if this approach is appropriate (as Python is quite flexible when it comes to dynamic code generation). Also injector.Injector.get.__doc__ mentions
Although this method is part of :class:Injector's public interface
it's meant to be used in limited set of circumstances.
For example, to create some kind of root object (application object)
of your application (note that only one get call is needed,
inside the Application class and any of its dependencies
:func:inject can and should be used):
Dependency injection frameworks are primarily for dependencies and because your Vehicles object is configured by the user at runtime it is more like application data than a dependency. It probably can't just be injected in one shot using MultiBinding unless you know it at compile time.
Likewise, you are right in saying that it would not be a good approach to construct your set of components by iterating and calling injector.getInstance(Bike.class) etc. For one, this is not good for testing.
However, because the objects contained in Vehicles have their own dependencies you can leverage the DI framework in the creation of your Vehicles object. Remember, also, that although you cannot bind a Provider to an implementation, when you bind a key Guice will inject that provider for you.
For the simple example in the post, consider creating a VehicleFactory. Inside, you could have something like the following:
public class VehicleModule implements Module {
#Override
public void configure(Binder binder) {
binder.bind(DieselEngine.class).toProvider(DieselEngineProvider.class);
binder.bind(PetrolEngine.class).toProvider(PetrolEngineProvider.class);
binder.bind(Bike.class).toProvider(BikeProvider.class);
}
}
public class DieselEngineProvider implements Provider<DieselEngine> {
#Inject
public DieselEngineProvider() {
//if DieselEngine has any dependencies, they can be injected in the constructor
//stored in a field in the class and used in the below get() method
}
#Override
public DieselEngine get() {
return new DieselEngine();
}
}
public class VehicleFactory {
private final CarFactory carFactory;
private final Provider<Bike> bikeProvider;
#Inject
public VehicleFactory(CarFactory carFactory, Provider<Bike> bikeProvider) {
this.carFactory = carFactory;
this.bikeProvider = bikeProvider;
}
public Bike createBike() {
return bikeProvider.get();
}
public Car createDieselCar() {
return carFactory.createDieselCar();
}
public Car createPetrolCar() {
return carFactory.createPetrolCar();
}
}
public class CarFactory {
private final Provider<DieselEngine> dieselEngineProvider;
private final Provider<PetrolEngine> petrolEngineProvider;
#Inject
public CarFactory(Provider<DieselEngine> dieselEngineProvider, Provider<PetrolEngine> petrolEngineProvider) {
this.dieselEngineProvider = dieselEngineProvider;
this.petrolEngineProvider = petrolEngineProvider;
}
public Car createDieselCar() {
return new Car(dieselEngineProvider.get());
}
public Car createPetrolCar() {
return new Car(petrolEngineProvider.get());
}
}
As you mention, there is the danger of this becoming 'factories all the way down', but Guice can help you here.
If the production of Engine becomes more complicated and involves a combination of different parameters, you can use tools like AssistedInject to auto-create the factories for you.
If you end up with a set of common dependencies and uncommon dependencies that you want to use to create different 'flavours' of an object then you have what is known as the robot legs problem then Guice can solve it using private modules.
Do note the following caveat from the Dagger 2 user guide:
Note: Injecting Provider has the possibility of creating confusing
code, and may be a design smell of mis-scoped or mis-structured
objects in your graph. Often you will want to use a factory or a
Lazy or re-organize the lifetimes and structure of your code to be
able to just inject a T.
If you follow this advice, it would seem that you would have to carefully balance using providers and using factories to create your Vehicle.
This is one of those topics I don't even know how to search in google (tried already, most of the results were for C#), so here I go:
I'm messing around with our huge application, trying to get to work a brand new DAO/Entity/Service/DTO.. euh...thing. I've been left more or less on my own, and, again, more or less, I'm getting to understand some of the hows and maybe one or two of the whys.
The thing is that I got all, the way "up", from the DB to the Service:
I got a DAO class which executes a query stored on an Entity class. After executing it, it returns the Entity with the values.
The service receives the Entity and, somehow, transforms the Entity to a DTO and returns it to whenever is needed.
My problem is with the "somehow" thing the code goes like this:
DTOClass dto = ClassTransformerFromEntityToDTO.INSTANCE.apply(entityQueryResult);
I went into ClassTransformerFromEntityToDTO and found this:
public enum ClassTransfomerFromEntityToDTO implements Function<EntityClass,DTO Class> ) {
INSTANCE;
#Override
public DTOClass apply(EntityClass entityInstance) {
/*Code to transform the Entity to DTO and the return*/
}
}
The class that this... thing, implements, is this:
package com. google .common . base;
import com. google .common . annotations. GwtCompatible ;
import javax. annotation .Nullable ;
#GwtCompatible
public abstract interface Function <F , T >
{
#Nullable
public abstract T apply (#Nullable F paramF) ;
public abstract boolean equals (#Nullable Object paramObject) ;
}
I'm in the classic "everyone who where at the beginning of the project fled", and no one knows why is this or what is this (The wisest one told me that maybe it had something to do with Spring), so, I have two main questions (which can be more or less answered in the same side):
1) What's this? What's the point of using an enum with a function to make a conversion?
2) What's the point of this? Why can I just make a class with a single function and forget about this wizardry?
not sure there's much to answer here... And I'm adding an answer to illustrate my thoughts with some code I've seen, but that you have is horrible. I've actually seem similar stuff. My guess is that that codes actually precedes Spring. It's used as some sort of Singleton.
I have seen code like this, which is worse:
public interface DTO {
find(Object args)
}
public class ConcreteDTO1 implements DTO {
...
}
public class ConcreteDTO2 implements DTO {
...
}
public enum DTOType {
CONCRETE_DTO1(new ConcreteDTO1(someArgs)),
CONCRETE_DTO2(new ConcreteDTO2(someOtherArgs))
private DTO dto;
public DTOType(DTO dto) {
this.dto = dto;
}
public DTO dto() {
return dto;
}
}
and then the DTOs are basically accessed through the Enum Type:
DTOType.CONCRETE_DTO1.dto().find(args);
So everyone trying to get hold of a DTO accesses it through the enum. With Spring, you don't need any of that. The IoC container is meant to avoid this kind of nonsense, that's why my guess is that it precedes Spring, from some ancient version of the app when Spring was not there. But it could be that someone was wired to do such things regardless of whether Spring was already in the app or not.
For that kind of stuff you're trying to do, you're better of with the Visitor pattern. Here's an example from a different answer: passing different type of objects dynamically on same method
It's me. From the future.
Turns out that this construct is a propossed Singleton Implementation, at least on "Effective Java 2nd edition".
So, yeah, Ulise's guess was well oriented.
I'm a huge fan of Java's annotations, but find it a pain in the neck to have to include Google's Reflections or Scannotations every time I want to make my own.
I haven't been able to find any documentation about Java being able to automatically scan for annotations & use them appropriately, without the help of a container or alike.
Question: Have I missed something fundamental about Java, or were annotations always designed such that manual scanning & checking is required? Is there some built-in way of handling annotations?
To clarify further
I'd like to be able to approach annotations in Java a little more programatically. For instance, say you wanted to build a List of Cars. To do this, you annotate the list with a class that can populate the list for you. For instance:
#CarMaker
List<Car> cars = new List<Car>();
In this example, the CarMaker annotation is approached by Java, who strikes a deal and asks them how many cars they want to provide. It's up to the CarMaker annotation/class to then provide them with a list of which cars to include. This could be all classes with #CarType annotations, and a Car interface.
Another way of looking at it, is that if you know you want to build something like this: List<Car> cars, you could annotate it with #ListMaker<Car>. The ListMaker is something built into Java. It looks for all classes annotated with #CarType, and populates the list accordingly.
You can create your own annotations and apply them to your own classes.
If you specify that an annotation is detectable at runtime, you can process it easily with reflection.
For example, you could use something like this to print the name of each field in a class that has been marked with the Funky annotation:
for (Field someField : AnnotatedClass.getClass().getDeclaredFields()) {
if (someField.isAnnotationPresent(Funky.class)) {
System.out.println("This field is funky: " + someField.getName());
}
}
The code to declare the Funky annotation would look something like this:
package org.foo.annotations;
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.FIELD)
public #interface Funky { }
Here's a class that uses the annotation:
package org.foo.examples;
import org.foo.annotations.Funky;
public class AnnotatedClass {
#Funky
private String funkyString;
private String nonFunkyString;
#Funky
private Integer funkyInteger;
private Integer nonFunkyInteger;
}
Here's some more reading on Annotations.
Here are the javadocs for the classes used above:
Retention annotation
RetentionPolicy enum
Target annotation
Field class
isAnnotationPresent() method
getDeclaredFields() method
I'm trying to understand your car example, but I'm not sure I follow what you want.
If you had a list of objects (Jaguar, Porche, Ferrari, Kia) that extend Car and are marked with various car-related annotations, you could create an object that filters the list based on annotations.
The code might look like this:
#WorldsFinestMotorCar
class Jaguar extends Car {
// blah blah
}
#BoringCar
class Porche extends Car {
// blah blah
}
#BoringCar
class Ferrari extends Car {
// blah blah
}
#IncredibleCar
class Kia extends Car {
// blah blah
}
You could implement an AnnotationFilter class that removes cars from the list that do not have a certain annotation.
It might look something like this:
List<Car> carList = getListOfRandomCars();
AnnotationFilter<Car> annoFilter = new AnnotationFilter<Car>(BoringCar.class);
List<Car> boringCars = annoFilter.filter(carList);
Is that what you want to do?
If so, it can definitely be done.
The implementation for AnnotationFilter might look something like this:
public class AnnotationFilter<T> {
private Class filterAnno;
public AnnotationFilter(Class a) {
filterAnno = a;
}
public List<T> filter(List<T> inputList) {
if (inputList == null || inputList.isEmpty()) {
return inputList;
}
List<T> filteredList = new ArrayList<T>();
for (T someT : inputList) {
if (someT.getClass().isAnnotationPresent(filterAnno)) {
filteredList.add(someT);
}
}
return filteredList;
}
}
If that's not what you're after, a specific example would be helpful.
Java haven't got anything built in as such, which is why Reflections came about. Nothing built in that's as particular as what you're saying..
User-defined Annotations: we shall see how to annotate objects that we may come across in day-to-day life. Imagine that we want to persistent object information to a file. An Annotation called Persistable can be used for this purpose. An important thing is that we want to mention the file in which the information will get stored. We can have a property called fileName within the declaration of Annotation itself. The definition of the Persistable Annotation is given below,
Persistable.java
#Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE})
public #interface Persistable
{
String fileName();
}
Annotations are just a way of tagging elements of a class; how these annotations are interpreted is up to the code that defines these annotations.
Is there some built-in way of handling annotations?
Annotations are used in so many different ways that it would be difficult to come up with a few "built-in ways" of handling them. There are source-level annotations (such as #Override and #Deprecated) that do not affect the behaviour of the code at all. Then there are runtime annotations that are usually very specific to a certain library, for eg. JAXB's binding annotations only make sense within a JAXBContext and Spring's autowiring annotations only make sense within an ApplicationContext. How would Java know what to do with these annotations simply by looking at a class which uses them?