Related
I have a general question about Kotlin collections.
Why are there mutable versions of so many collections (like the MutableList) when we have the val vs var distinction?
Well....ok...actually, I understand that val doesn't have anything to do with the 'mutability' of the object, but rather the 're-initializability' of the object.
But then that raises the question....why isn't MutableList the default?
TL;DR
Individually, mutable and immutable collections are able to expose useful features that can't co-exist in a single interface:
Mutable collections can be read from and written to. But Kotlin strives to avoid all runtime failures, therefore, these mutable collections are invariant.
Immutable collections are covariant, but they're...well...immutable. Still, Kotlin does provide mechanisms for doing useful things with these immutable collections (like filtering values or creating new immutable collections from existing ones). You can go through the long list of convenience functions for Kotlin's (immutable) List interface for examples.
Immutable collections in Kotlin cannot have elements added or removed from them; they can only be read from. But this apparent restriction makes it possible to do some subtyping with the immutable collections. From the Kotlin docs:
The read-only collection types are covariant...the collection types have the same subtyping relationship as the element types.
This means that, if a Rectangle class is a child of a Shape class, you can place a List<Rectangle> object in a List<Shape> variable whenever required:
fun stackShapes(val shapesList: List<Shape>) {
...
}
val rectangleList = listOf<Rectangle>(...)
// This is valid!
stackShapes(rectangleList)
Mutable collections, on the other hand, can be read from and written to. Because of this, no sub-typing or super-typing is possible with them. From the Kotlin docs:
...mutable collections aren't covariant; otherwise, this would lead to runtime failures. If MutableList<Rectangle> was a subtype of MutableList<Shape>, you could insert other Shape inheritors (for example, Circle) into it, thus violating its Rectangle type argument.
val rectangleList = mutableListOf<Rectangle>(...);
val shapesList: MutableList<Shape> = rectangleList // MutableList<Rectangle>-type object in MutableList<Shape>-type variable
val circle = Circle(...)
val shape: Shape = circle // Circle-type object in Shape-type variable
// Runtime Error!
shapesList.add(shape) // You're actually trying to add a Circle to a MutableList<Rectangle>
// If rectanglesList couldn't be put into a variable with type MutableList<Shape> in the first place, you would never have run into this problem.
At this point, you might be thinking: "So what? Kotlin could just add type-checks to all of the write-methods of Mutable Collections...then you could allow them to be covariant, and you wouldn't need separate immutable collections!"
Which is true, except that it would go completely against a core Kotlin philosophy; to avoid nulls and runtime errors whenever possible. You see, the methods of such a Collection would have to return null - or raise an Exception - whenever a type-check fails. This would only become apparent at runtime, and since that can be avoided by simply making Mutable Collections invariant...that's exactly what Kotlin does.
From the Kotlin docs:
The read-only collection types are covariant. This means that, if a Rectangle class inherits from Shape, you can use a List<Rectangle> anywhere the List<Shape> is required. In other words, the collection types have the same subtyping relationship as the element types. Maps are covariant on the value type, but not on the key type.
In turn, mutable collections aren't covariant; otherwise, this would lead to runtime failures. If MutableList<Rectangle> was a subtype of MutableList<Shape>, you could insert other Shape inheritors (for example, Circle) into it, thus violating its Rectangle type argument.
To paraphrase, if it's immutable you know all the types are the same. If not, you might have different inheritors.
I have read in many places that "getters and setters are evil". And I understood why so. But I don't know how to avoid them completely. Say Item is a class that has information about item name, qty, price etc...
and ItemList is a class, which has a list of Items. To find the grand total:
int grandTotal()
{
int total = 0;
for (Item item: itemList)
total += item.getPrice();
return total;
}
In the above case, how does one avoid getPrice()? The Item class provides getName, setName, etc....
How do I avoid them?
When should you use getters and setters?
Getters and setters are great for configuring or determining the configuration of a class, or retrieving data from a model
Getting the price of an item is an entirely reasonable use of a getter. That is data that needs to be available and may involve special considerations to protect the data by adding validation or sanitization to the setter.
You can also provide getters without setters. They do not have to come in pairs.
When shouldn't you use getters and setters?
Sometimes objects rely on internal properties that will never be exposed. For example, Iterators and internal collections. Exposing the internal collection could have dramatically negative and unexpected consequences.
Also, for example, let's say you are communicating via some HttpURLConnection. Exposing the setter for your HttpURLConnection means that you could end up with a very odd state should the connection be changed while waiting to receive data. This connection is something that should be created on instantiation or entirely managed internally.
Summary
If you have data that is for all intents and purposes public, but needs to be managed: use getters and setters.
If you have data that needs to be retrieved but under no circumstances should ever be changed: use a getter but not a setter.
If you have data that needs to be set for internal purposes and should never be publicly exposed (and cannot be set at instantiation): use a setter but not a getter (setter presumably prevents a second call affecting the internal property)
If you have something that is entirely internal and no other class needs to access it or change it directly, then use neither.
Don't forget that setters and getters can be private and even for internally managed properties, having a setter that manages the property may be desirable. For example, taking a connection string and passing it to the setter for HttpURLConnection.
Also note:
Allen Holub's article Why getter and setter methods are evil seems to be the source of OP's reasoning but, in my opinion, the article does a poor job of explaining its point.
Edit: Added summary
Edit 2: spelling corrections
It's a shame to see a small, vocal minority take a back lash against the whole "Getters and Setters" are evil debate. Firstly the article title is purposely provocative to draw you in, as should any blog post. I've in turn blogged about this before and several years later updated my opinions and ideas about this question. I'll summarise the best I can here.
Getters and setters (accessors) are not evil
They are "evil" (unnecessary) most of the time however
Encapsulation is not just adding accessors around private fields to control change, after all there is no benefit to added get/set methods that just modify a private field
You should write as much code as possible with the principle of "Tell, Don't Ask"
You need to use accessors for framework code, DTOs, serialisation and so forth. Don't try to fight this.
You want your core domain logic (business objects) to be as property free as possible however. You should tell objects to do stuff, not check their internal state at will.
If you have a load of accessors you essentially violate encapsulation. For example:
class Employee
{
public decimal Salary { get; set; }
// Methods with behaviour...
}
This is a crap domain object, because I can do this:
me.Salary = 100000000.00;
This may be a simple example, but as anyone who works in a professional environment can attest to, if there is some code that is public people will make use of it. It would not be wrong for a developer to see this and start adding loads of checks around the codebase using the Salary to decide what do with the Employee.
A better object would be:
class Employee
{
private decimal salary;
public void GivePayRise()
{
// Should this employee get a pay rise.
// Apply business logic - get value etc...
// Give raise
}
// More methods with behaviour
}
Now we cannot rely on Salary being public knowledge. Anyone wanting to give a pay rise to employees must do this via this method. This is great because the business logic for this is contained in one place. We can change this one place and effect everywhere the Employee is used.
The following sample is a brilliant example of boilerplate setters and getters.
class Item{
private double price;
public void setPrice(final double price){
this.price = price;
}
public double getPrice(){
return this.price;
}
}
Some coders think that this is called encapsulation, but in fact this code is exact equivalent of
class Item{
public double price;
}
In both classes price is not protected or encapsulated, but the second class reads easier.
class Item{
private double price;
public void setPrice(final double price){
if(isValidPrice(price))
this.price = price;
else throw new IllegalArgumentException(price+" is not valid!");
}
public double getPrice(){
return this.price;
}
}
This is a real encapsulation, the invariant of the class is guarded by the setPrice. My advice - don't write dummy getters and setters, use getters and setters only if they guard the invariant of your class
I have read in many places that "getters and setters are evil".
Really? That sounds crazy to me. Many? Show us one. We'll tear it to shreds.
And I understood why so.
I don't. It seems crazy to me. Either your misunderstood but think you did understand, or the original source is just crazy.
But I don't know how to avoid them completely.
You shouldn't.
how to avoid getPrice?
See, why would you want to avoid that? How else are you suppose to get data out of your objects?
how to avoid them???
Don't. Stop reading crazy talk.
When someone tells you that getters and setters are evil, think about why they are saying that.
Getters
Are they evil? There is no such thing as evil in code. Code is code and is neither good nor bad. It's just a matter of how hard it is to read and debug.
In your case, I think it is perfectly fine to use a getter to calculate the final price.
The "evil"
Usecase: you think you want the price of an item when buying something.
People sometimes use getters like this:
if(item.getPrice() <= my_balance) {
myBank.buyItem(item);
}
There is nothing wrong with this code, but it isn't as straight-forward as it could be. Look at this (more pragmatic approach):
myBank.buyItem(item); //throws NotEnoughBalanceException
It's not the buyers or the cashiers job to check the price of an item when buying something. It's the actually the bank's job. Imagine that customer A has a SimpleBank.java
public class SimpleBank implements Transaction {
public void buyItem(Item item){
if(getCustomer().getBalance() >= item.getPrice()){
transactionId = doTransaction(item.getPrice());
sendTransactionOK(transactionId);
}
}
}
The first approach seems fine here. But what if customer B has a NewAndImprovedBank.java?
public class NewAndImprovedBank implements Transaction {
public void buyItem(Item item){
int difference = getCustomer().getBalance() - item.getPrice();
if (difference >= 0) {
transactionId = doTransaction(item.getPrice());
sendTransactionOK(transactionId);
} else if (difference <= getCustomer().getCreditLimit()){
transactionId = doTransactionWithCredit(item.getPrice());
sendTransactionOK(transactionId);
}
}
}
You might think that you are being defensive when using the first approach, but actually you are limiting the capabilities of your system.
Conclusion
Don't ask for permission aka item.getPrice() , ask for forgiveness aka NotEnoughBalanceException instead.
getPrice() is accessing a private variable I'm assuming.
To answer your question directly, make the price variable public, and code something like (syntax may differ depending on language, use of pointers etc):
total += item.price;
However this is generally considered bad style. Class variables should generally remain private.
Please see my comment on the question.
How to avoid getters and setters? Design classes that actually act upon the data they hold.
Getters lie about the data anyway. In the Item.getPrice() example, I can see I'm getting an int. But is the price in dollars or cents? Does it include tax(es)? What if I want to know the price in a different country or state, can I still use getPrice()?
Yes, this might be beyond the scope of what the system is designed to do, and yes, you might just end up returning a variable's value from your method, but advertising that implementation detail by using a getter weakens your API.
'Evil' as .getAttention()
This has been discussed often, and even perhaps went a bit viral, as a result of the pejorative term "Evil" used in the dialog. There are times when you need them, of course. But the problem is using them correctly. You see, Professor Holub's rant isn't about what your code is doing now, but about boxing yourself in so that change in the future is painful and error prone.
In fact, all I have read by him carries this as its theme.
How does that theme apply to the class Item?
A look at the future of Item
Here is fictions's item class:
class Item{
private double price;
public void setPrice(final double price){
if(isValidPrice(price))
this.price = price;
else throw new IllegalArgumentException(price+" is not valid!");
}
public double getPrice(){
return this.price;
}
}
This is all well and good- but it is still 'Evil' in the sense that it could cause you a lot of grief in the future.
The grief is apt to come from the fact that one day 'price' may have to take different currencies into account (and perhaps even more complex barter schemes). By setting price to be a double, any code that is written between now and the 'apocalypse' (we're talking evil, after all) will be wiring price to a double.
It is much better (even Good, perhaps) to pass in a Price object instead of a double. By doing so you can easily implement changes to what you mean by 'price' without breaking the existing interfaces.
The takeaway on getters and setters
If you find yourself using getters and setters on simple types, make sure you consider possible future changes to the interface. There is a very good chance you shouldn't be. Are you using setName(String name)? You should consider setName(IdentityObject id) or even setIdentity(IdentityObject id) in case other identification models show up (avatars, keys, whatever). Sure you can always go around and setAvatar and setKey on everything, but by using an object in your method signature you make it easier to extend in the future to the objects that can use the new identity properties and not break the legacy objects.
A different perspective that is missing here so far: getters and setters invite to violate the Tell Don't Ask principle!
Imagine you go shopping in the supermarket. In the end, the cashier wants money from you. The getter/setter approach is: you hand over your purse to the cashier, the cashier counts the money in your purse, takes the money you owe, and gives back the purse.
Is that how you do things in reality? Not at all. In the real world, you typically don't care about the internal state of "autonomous" other "objects". The cashier tells you: "your bill is 5,85 USD". Then you pay. How you do that is up to you, the only thing the cashier wants/needs is he receives that amount of money from your side.
Thus: you avoid getters and setters by thinking in terms of behavior, not in terms of state. Getters/setters manipulate state, from the "outside" (by doing avail = purse.getAvailableMoney() and purse.setAvailableMoney(avail - 5.85). Instead, you want to call person.makePayment(5.85).
How to avoid getters and setters in Java?
Use Project Lombok
Cloudanger answer is is one, but you must also realize that the item list will likely contain many item objects with quantity ordered on it.
Solution : create another class in between them that stores your item in the item list and the qty ordered for that item (Let's say the class is called OrderLine).
OrderLine will have Item and qty as fields.
After that, code something like calculateTotal(int qty) in Item which return price*qty.
Create a method in OrderLine that call calculateTotal(qtyOrdered)
Pass the return value to the itemList.
This way, you avoid getters.
The ItemList will only know the total price.
Your code should live with your data.
Ask the Object who has the data to calculate the totalPrice instead of asking that object for raw data to calculate your totalPrice.
Really?
I don't think that. on the contrary the getters and setters help you to protect the consistense of the variables.
The importance of getters and setters is to provide protection to private attributes so that they can not be accessed directly for this it is best that you create a class with the attribute item in which you include the corresponding get and set.
Use a helper class ShoppingCart. Item's method item.addTo(ShoppingCart cart) would add the price to the totalSum of the cart using shoppingCart.addItem(Item item, int price)
Dependency from Item to ShoppingCart isn't disadvantageous if the Items are meant to be items of ShoppingCarts.
In the case where Items live solely for the ShoppingCart and the Item class is small, I would more likely have the Item as an inner class of the ShoppingCart, so that the ShoppingCart would have access to the private variables of the items.
Other thoughts
It would also be possible, although quite unintuitive design, to have the Item class count the sum (item.calculateSum(List<Item> items)), since it can access the private parts of other items without breaking encapsulation.
To others wondering why the getters are bad. Consider the given example where the getPrice() returns integer. If you would want to change that to something better like BigDecimal at least or a custom money type with currency, then it wouldn't be possible since the return type int exposes the internal type.
Getters and setters are evil because they break encapsulation and can unnecessarily expose an objects internal state and allow it to be modified in way it should not be. The following article elaborates on this problem:
http://programmer.97things.oreilly.com/wiki/index.php/Encapsulate_Behavior,_not_Just_State
You can avoid getter and setter at places by using _classname__attributename because that's the changed new name once you declare private to any attribute.
So if Item is the class with a private attribute declared as __price
then instead of item.getPrice() you can write _Item__price.
It will work fine.
I need a programming language (preferably scriptable and having JIT would be a plus, but these two are not necessary), which would allow something like this (example):
object
{
id;
new();
destroy();
}
info
{
descr;
}
event inherit object, info
{
trigger; //has id, descr, trigger
}
anon_event inherit event
{
- decr; //removes descr property, therefore anon_event has id, trigger, but NO descr
}
It would be especially nice, that it could also:
autogenerate id's on creation(new()),
allow specify which properties(members) are read public, private, const
autogenerate getters/setters for public properties (getters for const),
have logging/callback facilities for getters/setters,
allow select on property (selectallprop(descr) would select all instances with descr property) and on type selectalltype(event) would select all events and anon_events even if the members are not the same,
allow runtime inheritance, addition/removal of properties;
I think this is enough to give a general idea what type of language I am seeking. Basically, it's a component(list of properties as component members) based or looking from another point of view multiple inheritance without common ancestor.
Thank you for your tips
What you're asking for would (1) violate the Liskov Substitution Principle, an important tenet of object-oriented programming, and (2) would be almost impossible to use in practice, as removing arbitrary members from a class will very often lead to non-compiling or non-functional code as other members in that same class would much of the time depend on those removed members.
So what I'm saying is: this whole thing is a Bad Idea.
I have a grails project that is throwing the following exception:
org.springframework.dao.DataIntegrityViolationException: could not delete: [Role#4]; SQL [delete from role where id=? an
d version=?]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not del
ete: [Role#4]
In my Role domain, all I did to create this error, was change the definition of one of the variables from
List<RoleTool> roleTools = new ArrayList<RoleTool>()
to
ArrayList<RoleTool> roleTools = new ArrayList<RoleTool>()
Why is that?
It's bad practice in general to specify a concrete class as the declaration type, both in variable declarations and in method signatures. Unless you really need it to be an ArrayList, leave it as List to allow more flexibility.
I'm not entirely sure what's happening here, but Hibernate has its own collections classes that it uses for mapped collections, the most commonly used being org.hibernate.collection.PersistentList and org.hibernate.collection.PersistentSet. These implement the List and Set interfaces respectively, but do not extend ArrayList or HashSet or any typical concrete collection. Instead they're Hibernate internal classes that monitor changes to help with dirty detection when persisting, flushing, etc.
It's fine to declare the initial collection as an ArrayList since it's only read from when saving (it's Groovy though, so it's a lot cleaner to just use List<RoleTool> roleTools = []). But Hibernate needs the flexibility of implementing the List/Set interface when loading persistent instances.
Portfolio A → Fund 1
Portfolio A → Fund 2
Portfolio A → Fund 3
I couldn't frame my sentence without not using is/has. But between 1 & 2,
1) has a:
class PortfolioA
{
List<Fund> obj;
}
2) is a:
class PortfolioA : List<Fund>
{
}
which one do you think is better from the point of extensibility, usability? I can still access my funds either way, albeit with a small syntactical change.
I vote with the other folks who say HAS-A is better in this case. You ask in a comment:
when I say that a Portfolio is just a
collection of funds, with a few
attributes of its own like
TotalPortfolio etc, does that
fundamentally not become an "is-a"?
I don't think so. If you say Portfolio IS-A List<Fund>, what about other properties of the Portfolio? Of course you can add properties to this class, but is it accurate to model those properties as properties of the List? Because that's basically what you're doing.
Also what if a Portfolio is required to support more than one List<Fund>? For instance, you might have one List that shows the current balance of investments, but another List that shows how new contributions are invested. And what about when funds are discontinued, and a new set of funds is used to succeed them? Historical information is useful to track, as well as the current fund allocation.
The point is that all these properties are not correctly properties of a List, though they may be properties of the Portfolio.
do not 'always' favor composition or inheritance or vice-versa; they have different semantics (meanings); look carefully at the meanings, then decide - it doesn't matter if one is 'easier' than the other, for longevity it matters that you get the semantics right
remember: is-a = type, has-a = containment
so in this case, a portfolio logically is a collection of funds; a portfolio itself is not a type of fund, so composition is the correct relationship
EDIT: I misread the question originally, but the answer is still the same. A Portfolio is not a type of list, it is a distinct entity with its own properties. For example, a portfolio is an aggregate of financial instruments with an initial investment cost, a total current value, a history of values over time, etc., while a List is a simple collection of objects. A portfolio is a 'type of list' only in the most abstract sense.
EDIT 2: think about the definition of portfolio - it is, without exception, characterized as a collection of things. An artist's portfolio is a collection of their artwork, a web designer's portfolio is a collection of their web sites, an investor's portfolio consists of all of the financial instruments that they own, and so on. So clearly we need a list (or some kind) to represent a portfolio, but that in no way implies that a portfolio is a type of list!
suppose we decide to let Portfolio inherit from List. This works until we add a Stock or Bond or Precious Metal to the Portfolio, and then suddenly the incorrect inheritance no longer works. Or suppose we are asked to model, say, Bill Gates' portfolio, and find that List will run out of memory ;-) More realistically, after future refactoring we will probably find that we should inherit from a base class like Asset, but if we've already inherited from List then we can't.
Summary: distinguish between the data structures we choose to represent a concept, and the semantics (type hierarchy) of the concept itself.
The first one, because you should try to favour composition over inheritance when you can.
It depends whether the business defines a Portfolio as a group (and only a group) of funds. If there is even the remote possibility of that it could contain other objects, say "property", then go with option 1. Go with option 2 if there is a strong link between a group of funds and the concept of Portfolio.
As far as extensibility and usefullness 1 has the slight advantage over 2. I really disagree with the concept that you should always favour one over the other. It really depends on what the actual real life concepts are. Remember, you can always^ refactor.
^ For most instances of always. If it is exposed publicly, then obviously not.
I would go with option (1) - composition, since you may eventually have attributes specific to the portfolio, rather than the funds.
The first one, because it is "consists of". => Composition
I will differ with what appears to be the common opinion. In this case I think a portfolio is very little more than a collection of funds... By using inheritance you allow the use of multiple constructors, as in
public Portfolio(CLient client) {};
public Portfolio(Branch branch, bool Active, decimal valueThreshold)
{
// code to populate collection with all active portfolios at the specified branch whose total vlaue exceeds specified threshold
}
and indexers as in:
public Fund this[int fundId] { get { return this.fundList[fundId]; } }
etc. etc.
if you want to be able to treat variables of type Portfolio as a collection of funds, with the associated syntax, then this is the better approach.
Portfolio BobsPortfolio = new Portfolio(Bob);
foreach (Fund fund in BobsPortfolio)
{
fund.SendStatement();
}
or stuff like that
IS-A relation ship represents inheritances and HAS-A relation ship represents composition. For above mentioned scenario we prefer composition as PortfolioA has a List and it is not the List type. Inheritances use when Portfolio A is a type of List but here it is not. Hence for this scenario we should prefer Composition.