Calling service method from another service class - java

I have two service classes. WarehouseManagementService provides methods to administrate warehouses and stocks. SalesManagementService provides methods to manage customers and their orders.
To create an order, it is necessary to check, if the order item quantity is sufficient. For this I would use the method availableStock(Product p) in the WarehouseManagementService. But I do not know, how to call this method properly.
Do I have to create an instance of WarehouseManagementService in SalesManagementService? Or should I add the WarehouseManagementServiceInterface to the SalesManagementService constructor (dependency injection)?
What could a good architecture look like, to achieve a loose coupling of these two classes?
Thanks in advance.
public class WarehouseManagementService implements WarehouseManagementServiceInterface {
private DatabaseReadWarehouseInterface dbRead;
private DatabaseWriteWarehouseInterface dbWrite;
public int availableStock(Product p) {
// returns available quantity of product
}
}
public class SalesManagementService implements SalesManagementServiceInterface {
private DatabaseReadSalesInterface dbRead;
private DatabaseWriteSalesInterface dbWrite;
public void addOrder(Order o) {
// creates order, if product quantity is sufficient
}
}

You have the right feeling: The dependency should be injected. Just remember the Single Responsibility Principle: "A class should have only one reason to change".
By constructing WarehouseManagementService in SalesManagementService, you would add a second reason for SalesManagementService to change: When the way of constructing your WarehouseManagementService changes.
To solve it, you could either use a full-blown Dependency Injection framework, or simply start by adding a constructor parameter to SalesManagementService:
public class SalesManagementService implements SalesManagementServiceInterface {
private DatabaseReadSalesInterface dbRead;
private DatabaseWriteSalesInterface dbWrite;
private WarehouseManagementServiceInterface warehouseManagementService;
constructor(DatabaseReadSalesInterface dbRead,
DatabaseWriteSalesInterface dbWrite,
WarehouseManagementServiceInterface warehouseManagementService) {
this.dbRead = dbRead;
this.dbWrite = dbWrite;
this.warehouseManagementService = warehouseManagementService;
}
public void addOrder(Order o) {
// creates order, if product quantity is sufficient
}
}
Then in your main method, take care of instantiating WarehouseManagementService and pass it to SalesManagementService.
As a sidenote, you might want to move the construction of SalesManagementService and WarehouseManagementService into factories which give you a SalesManagementServiceInterface and a WarehouseManagementServiceInterface rather than the concrete classes ("program to interface, not implementation").

Related

How to alter the design so that entities don't use injections?

I've read and came to realize myself that entities (data objects - for JPA or serialization) with injections in them is a bad idea. Here is my current design (all appropriate fields have getters and setter, and serialVersionUID which I drop for brevity).
This is the parent object which is the head of the entity composition graph. This is the object I serialize.
public class State implements Serializable {
List<AbstractCar> cars = new ArrayList<>();
List<AbstractPlane> planes = new ArrayList<>();
// other objects similar to AbstractPlane as shown below
}
AbstractPlane and its subclasses are just simple classes without injections:
public abstract class AbstractPlane implements Serializable {
long serialNumber;
}
public class PropellorPlane extends AbstractPlane {
int propellors;
}
public class EnginePlane extends AbstractPlane {
List<Engine> engines = new ArrayList<>(); // Engine is another pojo
}
// etc.
In contrast, each concrete type of car requires a manager that holds some behavior and also some specific form of data:
public abstract class AbstractCar implements Serializable {
long serialNumber;
abstract CarData getData();
abstract void operate(int condition);
abstract class CarData {
String type;
int year;
}
}
public class Car1 extends AbstractCar {
#Inject
Car1Manager manager;
Car1Data data = new Car1Data(); // (getter exists per superclass requirement)
void operate(int i) { // logic looks weird but makes the example
if (i < 0)
return manager.operate(data);
else if (i > 1)
return manager.operate(data, i);
}
class Car1Data extends CarData {
int property1;
{
type = "car1";
year = 1;
}
}
}
public class Car2 extends AbstractCar {
#Inject
Car2Manager manager;
Car2Data data = new Car2Data();
void operate(int i) {
if (i < 31)
return manager.operate(data);
}
class Car2Data extends CarData {
char property2;
{
type = "car2";
year = 12;
}
}
}
// etc.
The CarxManager are #Stateless beans which perform operations on the data (the matching CarxData) given to them. They themselves further use injections of many other beans and they are all subclasses of AbstractCarManager. There are O(100) car types and matching managers.
The issue when serializing the State is that serializing the list of abstract cars does not play well with the injections in the subclasses. I'm looking for a design that decouples the injection from the data saving process.
My previous related questions: How to serialize an injected bean? and How can I tell the CDI container to "activate" a bean?
You can use the repository pattern. Place your business logic into a service and inject the repository (which abstracts the persistence mechanism) and manager into that. The repository hides the persistence implementation details from the business service and the entities are just simple POJOs.
It would look something like the below with Foo being the id of the entity Bar:
public class CarService {
#Inject
CarRepository carRepository;
#Inject
CarManager manager;
piblic void operate(final Foo foo) {
Bar myBar = carRepository.retrieve(foo);
manager.doSomethingTo(myBar);
carRepository.persist(myBar);
}
}
See also: Repository Pattern Step by Step Explanation, http://deviq.com/repository-pattern/. Some frameworks such as Spring Data JPA or deltaspike already implement the repository pattern for you, all you need to do is provide an interface like the following and they generate the implementation in the background:
#Repository
public interface CarRepository extends EntityRepository<Car, UUID> {}
Mark in answer to your request for more detail I am going to provide a remodeled solution because the example in the question really did not make sense to me and exhibits quite a few anti-patterns which lead to problematic software.
To find a good solution to the problem touches on a lot of different considerations, many of which are very large topics with many books written about them, but I will try my best to illustrate my thinking based on these to solve the above problem.
And apologies as I have no doubt you are aware of many of these, but I shall assume limited knowledge for the sake of clarity.
The first step in solving this problem is not about code, but about the model itself, model driven development is covered extensively in Eric Evan's book as mentioned in the comments below. The model should drive the implementation and should also exist on its own tier as part of a layered architecture and is made up of entities, value objects and factories.
Model Driven Development
In the model given in the question we have something called a State, which contains AbstractPlanes and AbstractCars. You are using JPA to persists the State which is effectively an aggregate of your planes and cars. Firstly calling anything a State in software is a bad smell because pretty much everything has some sort of state, but calling what we have here which is an aggregate the State makes even less sense.
How does one State differ from another? Is one car part of one State and another part of a different State or is it the case that all planes and cars belong to a single instance of State. What is the relationship between planes and cars in this scenario? How does a list of planes and a list of cars have any relation to a single State entity?
Well if State was actually an Airport and we were interested in how many planes and cars were currently on the ground, then this could be the correct model. If State was an Airport it would have a name or identity such as its airport code, but it does not and so...
... in this case, it seems that State is an object which is being used as a convenience to allow us to access the object model. So we are effectively driving our model by implementation considerations, when we should doing it the other way round and driving our implementation from our model.
Terms like CarData are also problematic for the same reason, creating a Car entity and then a separate object to store its Data is messy and confusing.
Failure to get the model right results in software that is at best confused and at worst completely non-functional. This is one of the largest causes of failed IT programmes and the bigger the project the harder this stuff is to get right.
Revised Model
So from the model I understand that we have Cars and we have Planes, instances of which are all unique entities with their own identity. They seem to me to be separate things and so there is no point in persisting them wrapped in some aggregate entity.
public class Plane {...}
public class Car {...}
Another consideration is the use of abstract classes in the model, generally we want to apply the principle of favoring composition over inheritance because inheritance can result in hidden behaviors and it can make a model hard to read. For example why have we got a ProperllerPlane and an EnginePlane? Surely a propeller is just a type of engine? I have greatly simplified the model:
public class Plane implements Serializable {
#Id
private String name;
private String model;
private List<Engine> engines;
The Plane is an entity with its own attributes and identity. There is no need to have additional classes which represent nothing in the real world just to store attributes. The engine object is currently an enum representing the type of engine used in the plane:
public enum Engine {
PROPELLER, JET
}
If the engine itself were to require an identity, as in real life engine serial numbers and things are tracked, then we would change this to an object. But we might not want to allow access to it except through a Plane entity instance, in which case the Plane will be known as a aggregate root - this is an advanced topic and I would recommend Evan's book for more details on aggregates.
The same goes for the Car entity.
#Entity
public class Car implements Serializable{
#Id
private String registration;
private String type;
private int year;
The above is all you need from what was provided in the question for the basis of your model. I have then created a couple of factory classes which handle creation of instances of these entities:
public class CarFactory {
public Car makePosrche(final String registrationNumber) {
Car porsche = new Car();
porsche.setRegistration(registrationNumber);
porsche.setType("Posrshe");
porsche.setYear(1986);
return porsche;
}
}
public class PlaneFactory {
public Plane makeSevenFourSeven(final String name) {
Plane sevenFourSeven = new Plane();
List<Engine> engines = new ArrayList<Engine>();
engines.add(JET);
engines.add(JET);
engines.add(JET);
engines.add(JET);
sevenFourSeven.setEngines(engines);
sevenFourSeven.setName(name);
return sevenFourSeven;
}
public Plane makeSpitFire(final String name) {
Plane spitFire = new Plane();
List<Engine> engines = new ArrayList<Engine>();
engines.add(PROPELLER);
spitFire.setEngines(engines);
spitFire.setModel("Spitfire");
spitFire.setName(name);
return spitFire;
}
}
What we are also doing here is separating out concerns as according to the Single Responsibility Principle each class should only really do one thing.
Now that we have a model we need to know how to interact with it. In this case we would most likely if using JPA persist the Cars in a table called Car and the Planes likewise. We would provide access to these persisted entities via repositories, CarRepository and PlaneRespository.
You can then create classes called services which inject the repositories (and anything else you require) to perform CRUD (Create Read Update Delete) operations on the instances of cars and planes and also this is the point where you can apply your business logic to these. Such as your method:
void operate(int i) {..}
By structuring your code this way you decouple the model (entities and value objects) from how they are persisted (repositories) from the services which operate on them as mentioned in your question:
I'm looking for a design that decouples the injection from the data saving process.
A possibility is to remove the property, so it won't be picked up by the serializers. This can be achieved be getting it programmatically.
private Car2Manager getCar2Manager() {
CDI.current().select(Car2Manager.class).get();
}
I would not consider this a clean solution, but it should be a workable "solution"
Also which might work is using JPA's #Transient:
#Inject
#Transient
Car2Manager manager;
I have not tested this, so it might not work.
What is the entry point?
Is this a web application, a rest service, a soap service, or event a scheduler?
Injection frameworks almost always separate data and service. Data are always POJO, containing absolutely no business logic. Here, assuming this is a rest-service, i will do the following:
public class SSOApplication {
public class State implements Serializable {
List<AbstractCar> cars = new ArrayList<>();
List<AbstractPlane> planes = new ArrayList<>();
// other objects similar to AbstractPlane as shown below
}
public abstract class AbstractPlane implements Serializable {
long serialNumber;
}
public class PropellorPlane extends AbstractPlane {
int propellors;
}
public class EnginePlane extends AbstractPlane {
List<Engine> engines = new ArrayList<>(); // Engine is another pojo
}
public abstract class AbstractCar implements Serializable {
long serialNumber;
abstract CarData getData();
}
public static class CarData {
String type;
int year;
}
public class Car2Data extends CarData {
char property2;
{
type = "car2";
year = 12;
}
}
public static class Car1Data extends CarData {
int property1;
{
type = "car1";
year = 1;
}
}
public static class Car1 extends AbstractCar {
#Override
CarData getData() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
public static class Car2 extends AbstractCar {
#Override
CarData getData() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
public static interface CarManager<T extends CarData> {
void operate(T car, int index);
default boolean canHandle(T carData) {
final TypeToken<T> token = new TypeToken<T>(getClass()) {
};
return token.getType() == carData.getClass();
}
}
#ApplicationScoped
public static class Car1Manager implements CarManager<Car1Data> {
public void operate(Car1Data car, int index) {
}
}
#ApplicationScoped
public static class Car2Manager implements CarManager<Car2Data> {
public void operate(Car2Data car, int index) {
}
}
#ApplicationScoped
public static class CarService {
#Any
#Inject
private Instance<CarManager<?>> carManagers;
public void operate(int index, AbstractCar car) {
final CarData carData = car.getData();
final CarManager<?> carManager = carManagers.stream()
.filter((mng) -> mng.canHandle(carData))
.findFirst()
.orElse(IllegalArgumentException::new);
carManager.operate(carData, index);
}
}
}
If you could alter your flow than perhaps you could do something like this:
class Car1InnerService {
#Inject
Car1Manager manager;
void operate(int i, Car1 car) {
if (i < 0)
return manager.operate(car.getData());
else if (i > 1)
return manager.operate(car.getData(), i);
}
}
}
I introduced some inner service which will operate on Car1 and use Car1Manager for it. Your AbstractCar class will also of course lose it's operate method because from now on your service will handle it. So now instead of calling car1.operate(i) you will have to make a call via Service like this:
public class SampleCar1ServiceUsage{
#Inject
Car1InnerService car1InnerService;
public void carManipulator(List<Car1> carlist){
int i = 0; //I don't know why you need this param therefore i just increment it
for(Car1 car: carlist){
car1InnerService.operate(i, car);
i++;
}
}
}
Of course you should introduce similar functionality for every other AbsractCar children (perhaps even extract some abstraction if necessary like for example AbsractCarInnerService which would define operate method or some interface which would do the same if you don't want any other solid methods in it). However this answer is still somehow related to #Justin Cooke answer and in my opinion you should definitely check those patterns which he mentioned in his post.

Design Patterns - One public class utilizing many hidden classes

I have gone through http://www.dofactory.com/net/design-patterns in trying to find out the most efficient to create a design pattern in which "one visible class utilizes many hidden classes" to create a fluent API. Below is the code I currently have:
public class VisibleClass {
Private OrderClass order;
private ReceiptClass receipt;
public VisibleClass makeOrder() {
if (!(order instanceof OrderClass))
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (!(receipt instanceof ReceiptClass))
receipt = new ReceiptClass();
receipt.print();
return this;
}
}
class OrderClass implements IOrder {
public void make() {}
}
class ReceiptClass implements IReceipt {
public void print() {}
}
interface IOrder { void make(); }
interface IReceipt { void print(); }
Here is how I am currently using the API:
public static void main(String[] args) {
VisibleClass x = new VisibleClass();
x.makeOrder().printReceipt();
}
It this a good approach? Can a better approach be used for it?
*EDIT: Also, I should add that the VisibleClass will implement all methods of the hidden classes.
Your approach is quite good. Here some recommendations:
1 Change class member types to their interfaces as for 'Program to an interface, not an implementation' principle:
public class VisibleClass {
private IOrder order;
private IReceipt receipt;
2 Do you really need to check class types in makeOrder and printReceipt methods ? Creating instances after null check seems enough:
public VisibleClass makeOrder() {
if (null == order)
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (null == receipt)
receipt = new ReceiptClass();
receipt.print();
return this;
}
3 This approach is valid until methods of VisibleClass will be called by a single thread. If you're going to place it in a multi-thread program, you should ensure that there are only one instances of OrderClass and ReceiptClass each. There are 3 ways you can follow:
a. Create instaces of OrderClass and ReceiptClass in constructor and make VisibleClass singleton.
b. Make OrderClass and ReceiptClass singleton and remove new lines.
c. Create instances surrounded with synchronized block in makeOrder and printReceipt methods.
one visible class utilizes many hidden classes
don't do that with business classes. Fluent syntax's is great for configuration etc, but not for plain business code.
The reason is that the class itself losses control over it's state which can put it in an inconsistent state (i.e generate faulty results).
There is even a principle called Law of Demeter which is about just that.
If you have a business requirement that a receipt should be printed on a new order you should just return it as a return value.
var receipt = visibleClass.makeOrder();
As for using interfaces for entity/business classes, why do you do that? why would you want to abstract away those? The usually do not have any other dependencies or different types of implementations.
You can try using the Facade Design pattern
Or may be try using a Decorator Pattern

What is the way to create API Library in Java

I am creating an API of a list of checking functions. There is an object passed in as an argument to be checked.
The object is like below:
public class People{
private String name;
private String address;
private int age;
private String job;
public getter() ...
public setter() ...
}
I create a class including a list of checking function to make sure the provided information is valid or not. For example:
public class checkingFunctions {
public static boolean checkName(People ppl){
perform the name checking function;
}
public static boolean checkAge(People ppl){
perform the age checking function;
}
}
I know the above way works as an API so that other people can call checkingFunctions.checkName(ppl). But is this the correct way to build the API that will be exposed to others as jar file ? I was thinking to create an interface of checkingFunctions like below:
public interface ICheckingFunctions {
boolean checkName(People);
boolean checkAge(People);
}
And let the checkingFunctions class to implement it, like
public class checkingFunctions implements ICheckingFunctions {
}
BUt it won't compile because the checkName and checkAge can not be declared as static if it is overriding a superclass method.
Or should I just use the interface and let it implement the interface, but remove the static from all checking method. So, if others want to use my API, they just instantiate the interface, and use instance.checkName() to call method ? is that a good way ?
I am wondering whether there there exists an industry standard or design pattern standard to create such an interface so that others can call it.
Thanks a lot.
How to design such an API very much depends on how your API is intended to be used.
If it for example turns out, that your People class is best implemented as a final class, and you want to make sure, that it is always checked in the same consistent way, then providing a number of public static check... methods is certainly a reasonable way to go.
If on the other hand you do not know in advance how your People class should be checked, then I'd consider providing an ICheckingFunctions interface that declares the necessary check... methods. But if you go this route, you will perhaps also need to provide a way for the user to change the actually used implementation of ICheckingFunctions.
You should also consider, that while using an interface is certainly much more flexible and extensible, it is also more work to maintain and it could also provide a possible security risk - e.g. if you allow users to change the used ICheckingFunction, then you no longer have control of how your People class is checked.
One possible way to implement such an API using an interface is allowing users to register/unregister the used ICheckingFunction in your class. A very naive implementation could look like this:
public final class CheckingFunctions {
private static ICheckingFunctions checkFunction;
public static void registerCheckFunction(ICheckingFunctions checkFunction) {
CheckingFunctions.checkFunction = checkFunction;
}
public static boolean checkName(People ppl){
return checkFunction.checkName(ppl);
}
public static boolean checkAge(People ppl){
return checkFunction.checkAge(ppl);
}
}
This is of course just a minimal example. In an actual API you would have to decide quite a lot of additional details. For example:
Is there only ever a single ICheckingFunctions instance available? If there may be more registered ICheckingFunctions - how do you choose which of these functions are used?
Who is allowed to register/unregister an ICheckingFunctions instance?
May the ICheckingFunctions be called from different threads?
etc.
You must also consider in which environment your API is going to be used. If you for example want to support usage of your API in an OSGI environment, then you could e.g. supply your ICheckingFunctions as an OSGI service.
Last but not least I would consider the following: May your users subclass the People class? If yes, then it would perhaps be a good idea to make the ICheckingFunctions interface generic, and allow registrations of implementations for different classes. Here again a very naive example of this approach:
public final class CheckingFunctions {
public interface ICheckingFunctions<T extends People> {
boolean checkName(T p);
boolean checkAge(T p);
}
private static Map<Class<?>,ICheckingFunctions<?>> checkFunctions = new ConcurrentHashMap<>();
public static <T extends People> void registerCheckFunction(ICheckingFunctions<T> checkFunction, Class<T> c) {
checkFunctions.put(c, checkFunction);
}
private static <T extends People> ICheckingFunctions<T> getRegisteredCheckFunction(Class<T> c){
ICheckingFunctions<T> checkFunction = (ICheckingFunctions<T>) checkFunctions.get(c);
if (checkFunction == null) {
// provide some reasonable default?
throw new IllegalStateException();
}
return checkFunction;
}
public static <T extends People> boolean checkName(T ppl, Class<T> c){
return getRegisteredCheckFunction(c).checkName(ppl);
}
public static <T extends People> boolean checkAge(T ppl, Class<T> c){
return getRegisteredCheckFunction(c).checkAge(ppl);
}
}

how to inject interface to class in java?

i have my DTO class that is :
public class EmailResponse {
// Make public to avoid getters and setters
public Email email;
public RequestData reqData;
public EmailResponse() {
super();
}
}
and i want to implement to it this interface:
public interface IAssertionErrorDo {
public void onErrorDo();
}
but i want to do it during execution, i don't want to touch "EmailResponse" because it would not be ok to make it implements that interface due they don't belong to the same layer, i mean, EmailResponse would belong to service layer and IAssertionError would belong to test layer. I am using TestNG.
Do you know how i could do this? Regards
EDIT:
My implementation is this:
EmailResponse emailResponse = emailService.getUserEmail(userId);
And the reason i want to do this "injection" is because i have
public class LoggingAssert
extends Assertion {
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingAssert.class);
private IAssertionErrorDo dataE;
#Override
public void onAssertFailure(IAssert a, AssertionError ex) {
LOGGER.info("[ERROR] " + a.getMessage());
if (this.dataE != null) {
this.dataE.onErrorDo();
}
}
public LoggingAssert setOnErrorDo(IAssertionErrorDo object) {
this.object = object;
return this;
}
}
loggingAssert.setOnErrorDo(emailResponse).assertNotNull(emailResponse.getEmail().getId(),
"Checking created email doesn't exists");
So i want to if assert fails execute method onErrorDo() from emailResponse
You could do
public class MyEmailResponse extends EmailResponse implements IAssertionErrorDo {
...
}
implementation calls in interfaces, you can call more than 1 interface if you want by adding commas to separate them..
to call interface methods you simply just use the method's name.
like this:
public class MyEmailResponse implements IAssertionErrorDo
{
public void onErrorDo() {//define it's behavior}
}
if you extend a class you use:
super.MyMethod()
to call the a method inside the extended class, but if you already have an extended class and want a method from another class you have to create an object for that class first then call it, thus:
MyClass mc = new MyClass();
if it is in a different package then
myPackage.MyClass mc = new myPackage.MyClass();
then you call your method from that class using the object you created, which is in this case mc.. so:
mc.MyMethod();
if you want it to return a variable then you will need to add a return statement in that method with the variable you want it to return.
interfaces are usually used for global an changing environments (dynamics), for example if you developed a program and it needs a driver to connect to databases then you will make an interface and send it to the database developers, and each one will fill the codes in that interface and send it back... this guarantees consistency.
when you implement an interface you have to define every method inside it (even if you leave it empty) and you cannot change the interface's methods names nor add... it is used in other areas as well, i don't think you need to use it in your case.

Understanding Abstract Factory pattern

I've read about abstract factory patter on wiki. But I don't understand really profit by using this pattern. Can you get an example in which is hard to avoid abstract factory pattern. Consider the following Java code:
public abstract class FinancialToolsFactory {
public abstract TaxProcessor createTaxProcessor();
public abstract ShipFeeProcessor createShipFeeProcessor();
}
public abstract class ShipFeeProcessor {
abstract void calculateShipFee(Order order);
}
public abstract class TaxProcessor {
abstract void calculateTaxes(Order order);
}
// Factories
public class CanadaFinancialToolsFactory extends FinancialToolsFactory {
public TaxProcessor createTaxProcessor() {
return new CanadaTaxProcessor();
}
public ShipFeeProcessor createShipFeeProcessor() {
return new CanadaShipFeeProcessor();
}
}
public class EuropeFinancialToolsFactory extends FinancialToolsFactory {
public TaxProcessor createTaxProcessor() {
return new EuropeTaxProcessor();
}
public ShipFeeProcessor createShipFeeProcessor() {
return new EuropeShipFeeProcessor();
}
}
// Products
public class EuropeShipFeeProcessor extends ShipFeeProcessor {
public void calculateShipFee(Order order) {
// insert here Europe specific ship fee calculation
}
}
public class CanadaShipFeeProcessor extends ShipFeeProcessor {
public void calculateShipFee(Order order) {
// insert here Canada specific ship fee calculation
}
}
public class EuropeTaxProcessor extends TaxProcessor {
public void calculateTaxes(Order order) {
// insert here Europe specific tax calculation
}
}
public class CanadaTaxProcessor extends TaxProcessor {
public void calculateTaxes(Order order) {
// insert here Canada specific tax calculation
}
}
If we need to just create objects in a code below 1-2 times in a code then we can use just new operator. And why we need in abstract factory?
You are missing half of the work :)
void processOrder(FinancialToolsFactory ftf,Order o) {
tft.createTaxProcessor().calculateTaxes(o);
tft.createShipFeeProcessor().calculateShipFee(o);
}
this code works as well as you pass a canadian or european implementation of FinancialToolsFactory (you can externalize the implementor class to external resource and instantiate with a Class.newInstance(), for example).
In this case one of the real benefits of pattern usage is not writing the code that implements the pattern, but who use that code!
PS: My answer is intentionally incomplete and try to answer just this specific question; a discussion about pattern and their benefits is too big!
You'd take advantage of this pattern if you were to support different implementations transparently. By delegating the decision of which implementation to use to the factory, you have a single point in your code where that decision is made (a.k.a. single responsibility).
The abstract factory pattern takes this concept beyond by aggregating related factories, such as different financial tools factories in your sample.
Now, if you only instantiate your financial tools once or twice in your code, using factories is over-engineering. The gain comes when you need to instantiate different implementations of the same interfaces in different places many times and you want to be able to work without worrying about which implementation you are using or how that decision is made.
There are quite some resources about this pattern on the web, and it's hard to guess what might be the best way of explaining its purpose in a way that sounds "plausible" for you.
But I think that the key point is:
With this pattern, someone who wants to create an instance of a particular implementation of an interface does not need to know what this particular implementation is. The call to the new operator is hidden inside the factory, and the user of the factory does not need to know the concrete class.
This makes it easier to switch the implementation later: You don't have to find and adjust all places where new ConcreteClass() was called and change it to new OtherConcreteClass() in order to use a different implementation. You just pass a different factory around, and everybody who uses this factory automatically creates instances of OtherConcreteClass (without even knowing that he does so...)

Categories

Resources