I have a Student class that has to have a property of a String ID, which has to be validated. I'm not sure whether to validate it inside the student class or the class that I'm implementing the Student class in. Does that make sense?
Assuming ID is final and immutable, then one approach is to have Student constructor throw an exception, probably new IllegalArgumentException("Invalid student ID");
You may additionally provide static method in Student class, which verifies if string is valid, in case you need to check it without creating Student object.
But the logic of determining if ID is valid or not should be in the Student class, I think.
If there are (or can be in future) different kind of student IDs, you could also consider abstract factory pattern, but sounds like that is bit of an overkill.
If Student already has any business inside use validate inside else use second one
Class Student
{
public boolean validate ()
{
//some logic to validation
}
}
Inside of Model or controller or Action
public boolean validate ()
{
//some logic to validation
}
One of the approach is to use validation object. For instance see the Validation approach uses in the Spring Framework. You create an object which implements the interface Validator with two methods: one to detect if the Validator can validate the instance to validate, and another one which validate it.
public class StudentValidator implements Validator<Student> {
public boolean supports(Student student) {
// ...
}
public void validate(Object target, Errors errors) {
// ...
}
}
This approach leads to separation of the code of the object and the way to validate it, offering more flexibility when combining validator:
you can combine several Validator even if the class hierarchy is not respected (POJO principle).
when you need to validate field with data from other system (for instance a database), this approach avoid to mix database / persistence code in the POJO domain class.
Please see the documentation of Spring about Validation.
Related
In my spring project I have such an aspect class for logging
#Aspect
#Component
public class BaseLoggingAspect {
private static final Logger logger = LoggerFactory.getLogger(BaseLoggingAspect.class);
#Target({ ElementType.FIELD, ElementType.PARAMETER })
public #interface NonLoggingField {
}
#Pointcut("execution(public * *(..))")
private void allPublicMethods() {
}
#Pointcut("within(img.imaginary.service.*)")
private void inServices() {
}
#Pointcut("within(img.imaginary.dao.*)")
private void inDao() {
}
#Before("allPublicMethods() && inServices() || inDao()")
public void logBeforeCall(JoinPoint joinPoint) {
if (logger.isDebugEnabled()) {
logger.debug("begin method {} in {} class with arguments: {}", joinPoint.getSignature().getName(),
joinPoint.getTarget().getClass().getSimpleName(), joinPoint.getArgs());
}
}
}
this aspect simply catches all the public methods of the service and dao layers and outputs to the log at the beginning of execution the name of the method, the name of the class, and the masi of the values of the arguments of the method
in this aspect, I created a NonLoggingField annotation that I want to apply to some fields of classes of those objects that can be passed to the parameters of these logged methods, for example this:
public class User {
#NonLoggingField
public String userEmail;
public name;
public User(String userEmail, String name) {
this.userEmail = userEmail;
this.name= name;
}
public String tiString() {
return String.format("user name: %s and his email: %s", name, userEmail);
}
}
the fact is that such objects will be written to the log through its toString method, but it is necessary that the email somehow does not get into the log using the notLoggingField annotation, while there are thoughts in my head to do through reflection, but there is no clarity how to do this without over difficult code using reflection, especially considering that objects may have objects of other types inside, which may have the same fields with annotations or collections with objects with such fields. perhaps the AspectJ library can help, but I can't find such mechanisms in it. Please help me come up with something
During runtime, a method parameter is just a value. The JVM does not know at this point if the caller called the method using constants, literals, fields or results of other method calls. That kind of information, you only see in the source code. In byte code, whatever dereferencing operation or computation necessary to determine the parameter's value (or a reference to the corresponding object) is done before calling the method. So there is no connection to the field annotation.
Would annotating method parameters be an alternative for you?
If your requirement is very specific, e.g. intercept field accesses from toString methods and return dummy values instead, if the field is annotated, that would be possible. But this would not be fool-proof. Imagine for example that toString calls a getter method instead of directly accessing the field or that a method other than toString logs the field. You do not always want to falisfy the field value on read access, because other parts of the application might rely on it working correctly. Not every toString call is made in order to log something.
I think you should solve the problem in another way, e.g. by applying filter rules for the logging tool you use. Or if you really want solve it at the application level, you could create an interface like
public interface PrivacyLogger {
String toStringSensitive();
}
and make each class containing sensitive information implement that interface. The logging aspect could then for each printed object determine if it is instanceof toStringSensitive(). If so, it would log the result of toStringSensitive() instead of toString(), i.e. in the simplest case something like
Object toBeLogged = whatever();
logger.log(
toBeLogged instanceof PrivacyLogger
? ((PrivacyLogger) toBeLogged).toStringSensitive()
: toBeLogged
);
Of course, you need to iterate over getArgs() and determine the correct log string for each object. Probably, you want to write a utility method doing that for the whole parameters array.
Moreover, in a complex class, the toStringSensitive() implementation should of course also check if its own fields are PrivacyLogger instances and in that case fold the values of their resapctive toStringSensitive() methods into itw own, so that it works recursively.
I am sorry I have no better news for you, but privacy is something which needs too be built into an application from the ground. There is no simple, fool-proof way to do that with one little aspect. The aspect can utilise the existing application infrastructure and avoid scattering and tangling, but it cannot decide on its own what needs to be prohibited from getting logged and what not.
I want to add unit tests for a method in class ClassToBeTested.execute(). ClassToBeTested is a business model class received from REST api. To call that method I have to:
create a class AAAclass (which must have 2 inner class mocked and stub 7 methods to put call the method I want to test)
put that mocked AAAclass in ClassToBeTested; ClassToBeTested depends on AAAclass
The AAAclass looks like:
public class AAAclass {
#SerializedName("BBBclass")
private BBBclass BBBclass;
public class BBBclass {
#SerializedName("CCCclass")
private CCCclass ccc;
public DDDclass getDDD() {
if (ccc != null) {
return ccc.getDDD();
}
return null;
}
}
private class CCCclass {
#SerializedName("DDDclass")
private DDDclass ddd;
public DDDclass getDDD() {
return ddd;
}
}
public class DDDclass {
}
}
I got the feeling that I'm doing sth wrong and it seems to be over mocking:
Don’t mock your model: Easier to read and you will may be add convenient constructor/factory methods to your production or test codebase.
So should I really add a special constructor just to use it in unit testing?
As was already mentioned it is hard to identify what are the objects and what is the context.
But it looks like the classes you'd mentioned are some DTOs but at the same time they have some business logic in their getters.
So first of all I would recommend you to extract the business logic to some other place (for instance some service). It should not be present in dto object.
Second. Why BBBclass, CCCclass and DDDclass are inner classes of AAAclass? Can't you make them static? Or event more can you extract them into separate classes? It is very important to decrease system complexity.
I think if you solve this issues you'll not need to mock such a complex object anymore.
At the same time remember if you're thinking of adding a constructor/method just for testability it is already a bad sign. It means that your system is becoming complex and abstractions don't work well. Try to rethink your abstractions.
I've been looking around the web for a while.
I'm trying to create an instance of a subclass dynamically, let me explain:
I have the following class:
Public abstract class Property
And a lot of sub class created from this class, for example the following two:
public class PropertyDns extends Property
Public class PropretyNetBios extends Property
I want the client to choose one of the subclass name, and then I need to create an instance of that class.
I'm going to have a lot of subclass that extends Property so switch-case statements will be exhausting:
So:
switch (user_input){
case "PropertyDns ": return new PropertyDns();
case "PropretyNetBios": return new PropretyNetBios();
.
.
.
}
will be terrible...
any ideas?
You can use one of the following two ways to achieve the result:
Create a factory method, which takes a String parameter, and based on the parameter, write up a switch to serve the required object.
The second option (and the recommended approach here) would be to dynamically create an instance from the class name using Class.newInstance
Using the second approach would make your solution easily extendable, and the addition of new classes won't need any structural changes.
A sample implementation of the second approach would be like:
public Property getProperty(String name) {
//Make sure the name contains full cannonical name of the class
return (Property) Class.forName(name).newInstance();
}
As I commented before, this problem can be solved with the Factory Pattern, if the number of classes is too large you can mix the Factory Pattern with an Annotation Processor to generate the factory. You need to create an annotation and a corresponding annotation processor.
Here is an example of the annotation you should create:
#Target(ElementType.TYPE) #Retention(RetentionPolicy.CLASS)
public #interface Property {
String name();
Class type();
}
Your property classes will look like this:
#Property(name="DnsProperty", class=Property.class)
public class DnsProperty extends Property{
...
}
You need to implement your own processor extending the class
javax.annotation.processing.AbstractProcessor
and register it at
/META-INF/services/javax.annotation.processing.Processor
The idea is to annotate each class to provide it's name, and generate the factory statements with the annotation processor, saving you from writing the exhausting switch-case statements. Explaining the annotation processors, as switch-case statements can be exhausting, so, you can read about it in the Java documentation, here is a blog post explaining annotation processors and here is the source code.
You need a Factory and a proper naming system for you classes(for example an enumeration), read about Factory pattern. This should work for you.
public class PropertyFactory {
public enum PropertyName {
DNS,
NET_BIOS
}
public Property createProperty(PropertyName name) {
switch (name) {
case DNS:
return new PropertyDns();
case NET_BIOS:
return new PropretyNetBios();
}
return null; //Or throw an exception
}
}
I have configured my spring Application as below:
// Spring MVC controller
#Controller
HelloController {
#ResponseBody
Student getData() {
return student from database;
}
}
public Class Student {
#Trim(device = "mob", trim=10)
#Trim(device = "desktop", trim=100)
String name ;
Address address;
}
public class Address {
#Trim(device = "mob", trim=10 )
#Trim(device = "desktop", trim=100 )
String addressInfo
}
Requirements:
After the Controller returns the Student, do modification of Student object and all complex attributes inside it based on the Annotation,
for example if the request was from mobile trim the student name to 10 and so on.
Approaches I can think of:
Recursively iterate on fields with annotation and modify fields.
Iteration on class fields every time can be hectic, as the class is complex and can nest up to n levels.
Create a List of Annotated fields at server start up and when then iterate on this list and apply changes to the target object.
I am currently struggling with both approachs. So would like to know whether there exists some prebuilt solutions or design patterns to handle such scenarios.
I actually coded the Reflection based approach and created a library some time back.
It uses reflection to identify annotation on fields and then takes the appropriate action based on the input device.
Here is the link for library
https://github.com/santoshjoshi/Adaptive-Device-Data-Filtering
I have 3 objects, a DTO called BalanceDTO which implements a interface RequestDTO and a Balance Entity. I created the DTO because the entity I can't use, JAXB compliance (legacy code).
The DTO is used in the web service layer, BalanceService, and the Entity in the API I integrate to from the web service. Between the web service and the API there is validation. RequestValidation which has sub validations for each type of RequestDTO i.e. BalanceRequestValidation.
The validation component takes in a RequestDTO as a parameter and then needs to do validation for the specific component. At the point of input the validation component doesn't know which object has been passed to it i.e. BalanceDTO, it only sees the interface.
I want to avoid using instanceof so I was thinking of using a visitor on the DTO so that it delegates itself to the validation that needs to be performed on it.
But the validation needs more/other components as well not just the BalanceDTO as input parameters and different validations needs different input params.
Is there another way to know which object you are working with and the validation to choose without using instanceof? Another design that I can follow?
You are well on the right track here - the Visitor design pattern is often the best way to avoid downcasting.
I am going to suggest a combination of the visitor and delegation design patterns, though let's walk through some alternatives.
Having the object do the validation itself via the RequestDTO interface is not viable since you need different components and the validation is not trivial in nature.
Using instanceof and downcasting looks a little messy, and the compiler won't complain if you add a new validatable class and forget to add the validator - you'll be relying on a runtime error via ...else { throw new IllegalArgumentException("Unknown RequestDTO subtype!"); }
The visitor design pattern is the classic way to avoid downcasting plus it also gives you a compiler error if you add a new class that should be validatable and forget to add the validation.
You can use accept() and visit() methods, or you can use method naming that is closer to your domain, e.g. validate(), like this:
public interface RequestDTO {
boolean validate(RequestValidation validator);
}
public class BalanceDTO implements RequestDTO {
// ...
#Override
public boolean validate(RequestValidation validator) {
return validator.validate(this);
}
}
public class RequestValidation {
// components...
public boolean validate(BalanceDTO balanceDTO) {
return true; // todo...
}
public boolean validate(AnotherDTO anotherDTO) {
return true; // todo...
}
}
If you want to go a bit further you can delegate the validation to specific validation components, like this:
public class RequestValidation {
BalanceRequestValidation balanceRequestValidation;
AnotherRequestValidation anotherRequestValidation;
public boolean validate(BalanceDTO balanceDTO) {
return balanceRequestValidation.validate(balanceDTO, a, b, c);
}
public boolean validate(AnotherDTO anotherDTO) {
return anotherRequestValidation.validate(anotherDTO, x, y, z);
}
}
Given I have understood your problem correctly, the visitor design pattern, possibly combined with the delegation design pattern, is indeed a good approach.