usage of visitor pattern - java

I have a class like this
public EmployeeRepositoryImpl{
public Employee save(final Employee employee) {
return employeeDao.save(sanitizeEmployee(employee));
}
Employee sanitizeEmployee(Employee employee){
employee.setName(cleanUpBadData(employee.getName());
employee.setPhone(cleanUpBadData(employee.getPhone());
employee.setAddress(cleanUpBadData(employee.getAddress());
......
return employee;
}
private static String cleanUpBadData(String attribute) {
//cleanbaddata here
return attribute;
}
}
I want to refactor this using visitor pattern incase tomorrow we need to add additional logic like cleanup Which I added today.I am not sure I did visitor pattern correctly since I do not have a accept method and Visitable.Can anyone please correct me the right way to do it.
I created
public interface EmployeeVisitor {
void visitEmployee(Employee employee);
}
public class EmployeeVisitorImpl implements EmployeeVisitor {
public void visitEmployee(Employee employee)
{
employee.setName(cleanUpBadData(employee.getName());
employee.setPhone(cleanUpBadData(employee.getPhone());
employee.setAddress(cleanUpBadData(employee.getAddress());
......
return employee;
}
private static String cleanUpBadData(String attribute) {
//cleanbaddata here
return attribute;
}
}

A correct implementation of the visitor pattern would look like this:
interface EmployeeVisitor {
void visitEmployee(Employee employee);
}
class CleanUpEmployee implements EmployeeVisitor {
void visitEmployee(Employee employee) {
...
}
}
class Employee {
void accept(EmployeeVisitor visitor) {
visitor.visitEmployee(this);
}
}
The visitor pattern is specifically designed to separate one or more algorithms from a class structure they operate on. There is no point to the visitor pattern unless there is a class structure you are trying to make your algorithms independent of. In your case you don't seem to have any extensions of Employee so there's really no value to using visitors - just make the algorithms methods of the class.
If your intention is to be able to add additional operations to the class without changing it then there are other patterns that are probably more useful. For example https://en.wikipedia.org/wiki/Strategy_pattern allows the behaviour to be selected at runtime and https://en.wikipedia.org/wiki/Command_pattern allows the behaviour to be encapsulated with its context.

Related

Create a mapping function depending on type hierarchy

I have an application that follows Domain Driven Design rules. One of the rules of DDD is that the domain layer should not depend on the infrastructure layer. I have a tool that checks if there are any dependencies (imports) from domain to infrastructure.
In my infrastructure layer, I have a class hierarchy like this:
In my domain layer, like this:
Now, I need to map my domain classes to the infrastructure entities in order to save them in my database.
I have an out port in my domain which is an interface:
// infra/ports/out/RuleRepository.java
public interface RuleRepository {
Rule save(Rule rule);
}
This interface in implemented in the infrastructure layer:
// domain/RuleRepositoryJpaAdapter.java
public class RuleRepositoryJpaAdapter implements RuleRepository {
// extends CrudRepository<RuleEntity, Long>
RuleCrudRepository jpaRepository;
RuleMapper mapper;
#Override
public Rule save(Rule rule) {
return jpaRepository.save(mapper.mapToEntity(rule))
.mapToDomain();
}
}
I'm looking for a way to implement mapToEntity without having to check the type of the rule. The best way would be to add a mapToEntity method to Rule, IpRule, BlackListRule but this would break the unit tests that check if there is any imports between the domain and infrastructure layer. If there any other way?
What I have right now:
public class RuleMapper {
public RuleEntity mapToEntity(Rule rule) {
if (rule instanceof IpRule) {
return new IpRuleEntity().mapFromDomain(rule);
} else if (rule instanceof BlackListRule) {
return new BlackListRuleEntity().mapFromDomain(rule);
} else {
throw new IllegalArgumentException("Unexpected argument of type " + (rule == null ? "null" : rule.getClass().getName()));
}
}
}
You could use something like the Visitor Pattern to implement double dispatch.
In this example, it could look something like this:
public abstract class Rule {
// Maps a rule to a result type T
public interface Mapper<T> {
T mapIpRule(IpRule rule);
T mapBlackListRule(BlackListRule rule);
}
public abstract <T> T map(Mapper<T> mapper);
// ...
}
public class IpRule extends Rule {
#Override
public <T> T map(Mapper<T> mapper) {
return mapper.mapIpRule(this);
}
// ...
}
public class BlackListRule extends Rule {
#Override
public <T> T map(Mapper<T> mapper) {
return mapper.mapBlackListRule(this);
}
// ...
}
public class RuleMapper implements Rule.Mapper<RuleEntity> {
public RuleEntity mapToEntity(Rule rule) {
return rule.map(this);
}
#Override
public RuleEntity mapIpRule(IpRule rule) {
return new IpRuleEntity();
}
#Override
public RuleEntity mapBlackListRule(BlackListRule rule) {
return new BlackListRuleEntity();
}
}
It has a nice property that there is compile-time check that all subtypes are handled correctly. If a new subtype of Rule is added later, it will need to implement the map method, which will require adding a method to the Rule.Mapper interface, which in turn will require the RuleMapper implementation to implement that method. In the example given in the question that uses runtime type checks with instanceof, it's possible to miss a case, resulting in an IllegalArgumentException at runtime.
However, you will need to judge whether the extra complexity is worthwhile for your specific situation. It might be that your existing RuleMapper is just fine.

implement generic class of child classes

I created an Athlete class.
public class Athlete {
private final int id;
private final String name;
private final Country sourceCountry;
public Athlete(int id, String name, Country sourceCountry){
this.id = id;
this.name = name;
this.sourceCountry = sourceCountry;
}
}
then I created the following interfaces and sub classes:
public interface IJumper {
public double jump();
}
public interface IRunner {
public double run();
}
public class Runner extends Athlete implements IRunner {
public Runner(int id, String name, Country sourceCountryCode) {
super(id, name, sourceCountryCode);
}
#Override
public double run() {
return Math.random();
}
}
public class Jumper extends Athlete implements IJumper {
public Jumper(int id, String name, Country sourceCountry) {
super(id, name, sourceCountry);
}
#Override
public double jump() {
return Math.random();
}
}
in addition, I created the following RunnerJumper class to create another type of athlete that can both run and jump:
public class RunnerJumper extends Athlete implements IRunner, IJumper {
public RunnerJumper(int id, String name, Country sourceCountry) {
super(id, name, sourceCountry);
}
#Override
public double jump() {
return Math.random();
}
#Override
public double run() {
return Math.random();
}
}
now, I want to create an Team class. the team should be team of runners or jumpers (team of runners can contain Runner & RunnerJumper and team of Jumpers can contain Jumper & RunnerJumper)
so I want the team to be generic..
in addition the team class should have method like "compete" (
something like: forEach Athlete of Team:
run or jump (depends the type of athlete..)
)
how can I achieve this kind of behaviour?
I tried to create it like this:
public class Team<C extends Athlete> {}
but in this form team of runners cannot contain RunnerJumper..
I also tried to create new interface Competitor:
interface Competitor {}
and have both IRunner & IJumper extend it..
this seems good at first:
public class Team<C extends Competitor> {}
but I don't understand how I can Implement the compete functionality in this form...
It's impossible to do it the way you imagine.
Types - in Java - serve to express guarantees. Things that are 100% certain about a piece of code. If a piece of code gets a Duck, there is 100% guarantee that it is also a Bird and an Animal.
But you cannot express relations like "it's either a Duck or a Bucket". You would need both to extend the same supertype and make sure that the type is only extended by these two; in general it would require multiple inheritance and sealed types.
And you cannot express relations which mix values with types, like "if the numberOfLegs == 8, then the type is Octopus". I have no idea how to call the aparatus required for this, but the structural types in Type Script, I think, can express such constraints. I think that duck typing is a prerequisite.
Coming back to Java: if there's a set of objects which can contain Runners or RunnerJumpers, the only thing that you can guarantee in the Java's type system is that all the objects are Runners. No generics, inheritance etc. can change that.
You can use one of the multitude of patterns to achieve your business goal:
refactor the jumping / running behavior into a separate classes, both implementing Action with a single perform method. Then create an interface with a single method: getActions, called, say, a Player. Then, your Team can iterate over Players, get actions for each one and call their perform method in an inner loop. The implementation of the getAction method can even return a static list of lambdas, so that you can access all your player's attributes from inside. This pattern allows you to keep the list of possible actions open (introducing new actions will not require you to recompile or touch your Team class).
if the list of possible actions is statically known by the Team, you can use the Visitor pattern - let the Team call the player's visit method, and the player can call Team's playerJumps(Jumper j) or playerRuns(Runner r).
Or you can use other mechanisms of the language: reflection and casting (this will also make the list of possible actions static).
What you could do is you could create two Team classes, one for the runners and one for the jumpers, like so:
public interface Team {
public void compete();
}
public class TeamRunners implements Team {
private List<Runner> runners;
private List<RunnerJumper> runnerJumpers;
public Team(List<Runner> runners, List<RunnerJumper> runnerJumpers) {
this.runners = runners;
this.runnerJumpers = runnerJumpers;
}
#Override
public void compete() {
for (Runner runner : runners) {
runner.run();
}
for (RunnerJumper runnerJumper : runnerJumpers) {
runnerJumper.run();
runnerJumper.jump();
}
}
}
public class TeamJumpers implements Team {
private List<Jumper> jumpers;
private List<RunnerJumper> runnerJumpers;
public Team(List<Jumper> jumpers, List<RunnerJumper> runnerJumpers) {
this.jumpers = jumpers;
this.runnerJumpers = runnerJumpers;
}
#Override
public void compete() {
for (Jumper jumper : jumpers) {
jumper.jump();
}
for (RunnerJumper runnerJumper : runnerJumpers) {
runnerJumper.run();
runnerJumper.jump();
}
}
}

I am implementing factory design pattern in java

I am implementing factory design pattern in java where I want to keep one overloaded method in abstract class. Will it violate the factory pattern concept?
Or please suggest whether this is right way to implement Factory design pattern ?
abstract class A{
void meth(int a);
void meth(int a,int b);
}
class Factory{
public static A factoryMethod(int a){
if(a==1){
return new Ob1();
}else{
return new Ob2();
}
}
}
class Ob1 extends A{
void meth(int a){}
void meth(int a,int b){}
}
To implement the Factory Pattern first you need to consider what the Factory will produce. Let's produce Vehicles.
public VehicleFactory {
public Vehicle newVehicle(String type) {
...
}
}
which will produce Vehicles according to the class hierarchy below.
public interface Vehicle {
public List<Door> getDoors();
}
public class Motorcycle implements Vehicle {
public List<Door> getDoors() {
return Collections.<Door>emptyList();
}
}
public class SportsCar implements Vehicle {
public List<Door> getDoors() {
return Collections.<Door>unmodifiableList(Arrays.asList(new Door("driver"), new Door("passenger"));
}
}
public class Hatchback implements Vehicle {
public List<Door> getDoors() {
return Collections.<Door>unmodifiableList(Arrays.asList(new Door("driver"), new Door("passenger"), new Door("back"));
}
}
Then your VehicleFactory method newVehicle(...) might look like
public Vehicle newVehicle(String type) {
if ("motorcycle".equals(type)) { return new Motorcycle(); }
if ("sports car".equals(type)) { return new SportsCar(); }
if ("hatchback".equals(type)) { return new Hatchback(); }
return null;
}
Now the main question is "Why would you want to do this?"
Sometimes you want a nice clean interface for building a lot of
related items. You give the related items an Interface and a Factory
to build them. This allows someone using this part of the software to
simply pull in the Interface class and the ItemFactory. They don't
see the individual details, which simplifies their code.
Since you hid the implementation details of all of the Vehicles in the above code, if you had a programming error (or wanted to add something), you can fix one of the Vehicles (or add a new Vehicle) to the factory and re-release the library (JAR file) containing the VehicleFactory.
You know that other people have been using the VehicleFactory methods, so you don't have to worry about their code breaking at compile time, and unless you were careless, you can also assure that it will work at runtime.
This is not the same as saying that the behavior won't change. The new implementations of Vehicle will be returned back, hopefully with fewer embedded bugs. Also, since they didn't ask for the "new vehicles" you might have added they won't see them, until they call newVehicle("station wagon") or something like that.
Also, you can change how the Vehicles are built up. For example, if you later decide that you don't want a simple "just construct it in one pass" implementation style, you could alter 'newVehicle(...)' like so
public Vehicle newVehicle(String type) {
Chassis chassis;
if ("motorcycle".equals(type)) {
chassis = new TwoWheelChassis();
} else {
chassis = new FourWheelChassis();
}
return new ComponentVehicle(chassis, getDoorCount(type));
}
where ComponentVehicle implements Vehicle and for some reason requires an explicit Chassis object.
--- update seeing the "number of methods" question in the comments ---
A Factory pattern is not really about the number of methods, but about one method having the ability to build an abstract thing out of one or more concrete things.
So in the example above, I could have
public VehicleFactory {
public Vehicle newVehicle(String type) { ... }
public Vehicle newRedVehicle(String type) { ... }
public Vehicle newBlackVehicle(String type) { ... }
}
And they would all be acceptible factory methods with respect to the type of the Vehicle, but they would not be factory oriented methods with respect to the color of the Vehicle.
To get a factory method that could handle Type and Color at the same time, the factory method
public Vehicle newVehicle(String type, String color) { ... }
might be added. Note that sometimes some combinations just don't make any sense, so it might not be worthwhile packing all factory methods down into a single factory method.
Any method in your factory object is not really a factory method unless it has the potential to return back more than one base type of the interface. Likewise it is not a factory method if you have to specify how to build the object outside of the method.
If you need to pass control of how to build a Vehicle to the client of your "it would have been a factory" method while providing some security they used it in a sane manner, you want the Builder pattern. An example of how a Builder Pattern differs can be seen in the client code below
VehicleBuilder builder = new VehicleBuilder();
builder.addDoor("driver");
builder.addDoor("passenger");
builder.paintVehicle("red");
Vehicle vehicle = builder.getVehicle();
Factory pattern is a vague term, no? There are Simple factories, Factory methods, and Abstract factories. I think you're talking about a Simple Factory here. https://www.codeproject.com/Articles/1131770/Factory-Patterns-Simple-Factory-Pattern
Here is an example of Java factory implementation.
Let's say we have a requirement to create multiple currencies support and code should be extensible to accommodate new Currency as well. Here we have made Currency as interface and all currency would be a concrete implementation of Currency interface.
Factory Class will create Currency based upon country and return concrete implementation which will be stored in interface type. This makes code dynamic and extensible.
Here is complete code example of Factory pattern in Java.
The Currency classes:
interface Currency {
String getSymbol();
}
// Concrete Rupee Class code
class Rupee implements Currency {
#Override
public String getSymbol() {
return "Rs";
}
}
// Concrete SGD class Code
class SGDDollar implements Currency {
#Override
public String getSymbol() {
return "SGD";
}
}
// Concrete US Dollar code
class USDollar implements Currency {
#Override
public String getSymbol() {
return "USD";
}
}
The Factory:
// Factory Class code
class CurrencyFactory {
public static Currency createCurrency (String country) {
if (country. equalsIgnoreCase ("India")){
return new Rupee();
}else if(country. equalsIgnoreCase ("Singapore")){
return new SGDDollar();
}else if(country. equalsIgnoreCase ("US")){
return new USDollar();
}
throw new IllegalArgumentException("No such currency");
}
}
// Factory client code
public class Factory {
public static void main(String args[]) {
String country = args[0];
Currency rupee = CurrencyFactory.createCurrency(country);
System.out.println(rupee.getSymbol());
}
}
Check out for more Java Factory pattern examples.

Trying to implement the Visitor pattern

I'm trying to get to grips with the visitor method in Java.
I'm trying to write a very simple program to get used to it. Basically it is a Food Menu. I want to read in user input (food type (starter, main course...) and the name of the food (pasta, fish...)) and then add this item to the menu.
I'm fairly sure I have the code correct so far, I'm just struggling to figure out how I pass the values read in from the user.
One of my friends who is also a programmer told me that you are supposed to have all of your functionality in the visitor classes (or at least as much as possible).
So do I take the user input and create it into a Menu Element? Then have the visitor add the element to the Menu? (I also want to be able to remove items from the Menu but I'm assuming that this is just reverse engineering the method to add)
Or do I not go so far as to have the visitor actually add the element. For example; would I just create the Menu Element and then pass that, then have the adding functionality in the Menu class?
To me it would make sense to have the visitor actually add the item, as it is functionality I want to keep specific to the adding visitor, but every time I try to implement I keep getting told that I have to make the arraylist containing the Menu Elements static, and I can't help but think I am doing it wrong.
I'm not 100% sure that the Visitor Pattern is correct for what I am trying to do?
Personally I believe I am either really, really close..... or WAY OFF!!
Any help you guys can offer would be great, even if you can point me towards a good tutorial that will help explain how to correctly use this pattern.
Here is what I have so far:
interface MenuElementVisitor {
void visit(Starter starter);
void visit(MainCourse mainCourse);
void visit(Desert desert);
void visit(Drinks drinks);
void visit(Menu menu);
}
Menu Element Classes
interface MenuElement {
void accept(MenuElementVisitor visitor); // MenuElements have to provide accept().
}
class Starter implements MenuElement {
private String name;
public Starter(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(MenuElementVisitor visitor) {
visitor.visit(this);
}
}
class MainCourse implements MenuElement {
private String name;
public MainCourse(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(MenuElementVisitor visitor) {
visitor.visit(this);
}
}
class Desert implements MenuElement {
private String name;
public Desert(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(MenuElementVisitor visitor) {
visitor.visit(this);
}
}
class Drinks implements MenuElement {
private String name;
public Drinks(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(MenuElementVisitor visitor) {
visitor.visit(this);
}
}
The Menu Class
class Menu implements MenuElement {
MenuElement[] elements;
public MenuElement[] getElements() {
return elements.clone(); // Return a copy of the array of references.
}
public Menu() {
this.elements = new MenuElement[] {
new Starter("Soup"),
new Starter("Pate"),
new MainCourse("Steak"),
new MainCourse("Fish"),
new Desert("Ice Cream"),
new Desert("Apple Tart"),
new Drinks("7up"),
new Drinks("Wine"),
};
}
public void accept(MenuElementVisitor visitor) {
for(MenuElement element : this.getElements()) {
element.accept(visitor);
}
visitor.visit(this);
}
}
Visitor to Add Items to the Menu
class MenuElementAddVisitor implements MenuElementVisitor {
System.out.println("Press 1 for Starter, 2 for Main Course, 3 for Desert or 4 for Drinks");
int MenuElementType = Console.readInt();
System.out.println("Type the name of the Menu Element you want to add");
String MenuElementName = Console.readString();
Visitor to Remove Items from the Menu
class MenuElementRemoveVisitor implements MenuElementVisitor {
}
Run the code demo
public class VisitorDemo {
static public void main(String[] args) {
Menu menu = new Menu();
menu.accept(new MenuElementAddVisitor());
menu.accept(new MenuElementRemoveVisitor());
}
}
I think that your "adding" visitor shouldn't know about the fact that you use Command-Line arguments to indicate your menu names.
Indeed, this breaks SRP => Single Responsibility Principle because adding and reading are two actions so two responsibilities. To understand that, imagine you decide to read menu names now from file ... you'll have to open and recode your "adding" visitor class.
You should have a main generic class who just know about String (for the names) and specialized class someone can create or eventually use yours to precise from where arguments are provided.
So in your example, you should try to replace Console.readInt(); and Console.readString() with an int method parameter and a String method parameter.
You may not have a need for a vistor in this case. The gang-of-four says:
" ... Use the Visitor pattern when
an object structure contains many classes of objects with differing interfaces, and you want to perform operations on these objects that depend on their concrete classes.
many distinct and unrelated operations need to be performed on objects in an object structure, and you want to avoid "polluting" their classes with these operations. Visitor lets you keep related operations together by defining them in one class. When the object structure is shared by many applications, use Visitor to put operations in just those applications that need them.
the classes defining the object structure rarely change, but you often want to define new operations over the structure. Changing the object structure classes requires redefining the interface to all visitors, which is potentially costly. If the object structure classes change often, then it's probably better to define the operations in those classes. ..."
If you really want a visitor pattern for something similar see this answer.

Is it okay to use the instanceof operator to implement two parallel hierarchies of functions and arguments to those?

Is it bad practice to use the instanceof operator in the following context?
public interface IWriter {
public abstract void write(Dto dto);
}
public abstract class Dto {
private long id;
public void setId(long id) {this.id = id;}
public long getId() {return id;}
}
public class DtoA extends Dto {
...
}
public class DtoB extends Dto {
...
}
public class MyWriterA implements IWriter {
#Override
public void writer(Dto dto) {
if (!(dto instanceof DtoA))
return;
...
}
}
public class MyWriterB implements IWriter {
#Override
public void writer(Dto dto) {
if (!(dto instanceof DtoB))
return;
...
}
}
There is a lot of myths about the use of that operator and I am not completely
sure that what I am doing is not bunk.
I have a lot of different writer implementations
which I want to combine in one interface. The problem is not every DTO is applicable for every writer. In my actual code there is a deep hierarchy of DTOs, which extend DtoA and DtoB, and either the
hierarchy branch of DtoA or DtoB is applicable for a writer, but only in a few cases both.
Should I avoid using the abstract class Dto as argument for the abstract write(Dto dto) method?
EDIT: Please read the comments on the accepted answer.
Sometimes there's no getting around using instanceof - there is no need to feel shame.
Typing IWriter may help:
public interface IWriter<T extends Dto> {
public abstract void write(T dto);
}
then
public class MyWriterA implements IWriter<DtoA> {
#Override
public void writer(DtoA dto) {
// No need for instanceof, because it can't be anything else
...
}
}
Perhaps a combination of such typing and Brian Agnew's worthy answer would do the trick.
How is the code calling the IWriter? Presumably you've got to determine the type up there too? In which case you already know what kind of writer you need. You're already dispatching on the basis of Type.
Your writers are not really substitutable WriterA only does As and so on. In which case you're not gaining anything by claiming they are in an inheritance hierarchy.
Have you looked at double-dispatch or the Visitor pattern ?
Essentially your Writer and DTO objects would mediate to call the correct methods e.g.
public void writer(Dto dto) {
dto.doSomething(writer);
}
and the doSomething() method called would depend on the type of the Dto. Your Dto object would implement a version for MyWriterA/B.
Using instanceOf isn't unavoidable, but is often a design smell, indicating that something isn't right, or could be done better.

Categories