1

I am designing the service layer of my web application. There are some scenario which I need to get the Orders based on the Product.

When I design the API, should I pass by object or value?

Order order = new Order();
String orderId = "1";
order.setId(orderId);

List<Product> products = getProductByOrder(order);

List<Product> products = getProductsByOrderId(orderId)
3
  • 7
    Those terms mean something completely different. You might want to clarify. Commented Oct 3, 2014 at 14:40
  • Why not have both, since one is trivially derived from the other? (Mostly devil's advocate here, I don't know if the additional surface area is worth it.) Commented Oct 3, 2014 at 14:42
  • if it was me I would have a map<String,Order> where String is the orderId, then get the order/orderId(depending on what you want to show) by using orderID. Commented Oct 3, 2014 at 14:43

4 Answers 4

3

Well, i think you are making some mistakes with this concepts, in this two ways you are making references to this objects, order and orderId(since String is an object too.)

But the best approach in this case is using getProductsByOrderId(orderId) because your code will be loosely coupled, since your other layer won't have to know about an Order object, and just know about a string object. If we can pass simpler objects as parameters, we do.

Good example from @Pienterekaak posted as comment:

"In many cases its easier to obtain just an orderid, then a whole order object. (for example, you would include an order id in a REST call, not the whole order object)"

Sign up to request clarification or add additional context in comments.

9 Comments

But it has to know about an orderid, which is a part of an order. Imo it would be better to implement it in the Order class, so you can call a property like List<Product> order.Products
This is less efficient than just passing the Order. Because now you have to look up the order based on the id. Extra processing. If you just give a pointer to the Order itself then there is no lookup.
That's the point, if i'm passing the orderid, the method which is receiving doesn't need to know that it is part of an order object. If we can pass simpler objects as parameter, we do. Btw, good point @brso05 - Up to your comment
@brso05 That depends fully on the implementation (maybe all the method does is: select * from products where orderid=order.getOrderId(). Talking API design, i would say go for the orderId, much more loosely coupled, and in many cases its easier to obtain just an orderid, then a whole order object. (for example, you would include an order id in a REST call, not the whole order object)
On the other hand, your library doesnt have to know the Order class, that saves a dependency there (loosely coupled). You always have these kind of tradeoffs. In this case i would go for less dependencies, and an easier to call API by using just the value you need.
|
1

From my experience i would go for:

List<Product> products = getProductsByOrderId(orderId)

With the argument, that for the first call, you need an Order object, and for the second call you just need an id, which is probally easier to obtain.

Comments

1

Actually both of these are passing by value. Java only passes by value. In both of these cases you are passing a reference to an Object (String) or (Order). You are passing as a value the location of memory where this object is (pointer). If you are passing a primitive type like int it passes the value like 1 but if you are passing an object it passes the value of the pointer to the object ie. memory location. In any case you are always passing by value.

If you have a Map storing the Order objects it is actually more efficient to pass the Object itself because you are directly passing the pointer for that object. If you pass the String id of 1 you are passing a pointer to that string then you would have to use that string to look up your Order object which is actually adding more processing then just passing a pointer to the object directly.

4 Comments

You've considered one case where they have a Map<Order, Product>. What about other cases? What if they have Map<String, Product>?
Read between the lines sometimes you have to infer things based on what the OP asks...I just gave him an example based on what he asked.
I don't know what lines you are talking about. You are criticizing another answer for only considering one possibility, but do the same thing in your answer.
Because my answer was based on what he asked the other user was giving him an answer that wasn't based on his question (infering what the user is wanting).
0

OrderId belongs to the concept of an order. If you pass the order id, the product has to know, how an order is identified. That's not loosely coupled.

If you put the method into Order, so you can call a property like List order.Products only the Order concept knows, how products and orders are connected, which sounds right to me. Products shouldn't know anything about orders but orders should know about products.

If you use Hibernate, you could configure it to do it for you with an one-to-many, since orderId is a primary key in your order table.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.