I mostly agree with your idea about static methods. But what about operations that depend of both arguments equally? For example Math.min or Math.max. Should we really have a 5.min(3)? It sounds counter intuitive to me. I think it is better to have a static method called min(3,5). In an ideal language, this would be a global function. Notice that since it has no global state, no testability is lost.
Wouldn't the last change make it more difficult to promote a User to SuperUser?, I mean, wouldn't the viability of this change be dependant on stuff like this?
I cannot agree more. Static state is terrible! People often say that it is not the case, but once it bites you in the behind, you will never think the same again.
I have a question, what would be a possible solution to a global class that returns some state when a get() (yes, static) is called on it? I would love to refactor the code in such away that get() is no longer needed. Any advice would be greatly appreciated... this has been annoying me for a long long time.
I disagree with you in that I think static methods are just fine as long as they do not maintain global state. This is mainly due to the DRY principle.
Given a function of two differently typed arguments, let's call them X and Y, it would be bad design to implement X(Y) and Y(X) in different places in your code as whenever X(Y) had to be updated, so would Y(X). This may seem like a corner case but many variations on this theme frequently occur in large projects.
That User/SuperUser/AgentUser thing is beautiful in theory, but hard to achieve in practice.
What if you can change the type of a user, from 'agent' to 'super'? Most languages won't let you do it. ORM frameworks (Hibernate) won't let you do it. At least not in a nice, clean way. Also, what about the 'composition over inheritance' principle?
About the static methods rant, how to avoid an explosion in the number of methods in basic classes, like string and number? String.toJDOMElementTree() would be a candidate?
I don't disagree with you, in that people could do much, much better.
It's just funny. People discuss design principles as if they were a cohesive, coherent, single body of absolute truth, when in reality most of them are disconnected, contradictory, context-specific rules, that are all correct individually, but nearly impossible to be fully followed together.
For example, how to maximize encapsulation of a class, without violating the 'S' in SOLID? Or, how to maximize reuse (DRY) without raising coupling, while keeping it simple?
What I'm trying to say is, to design is to make choices and to balance trade-offs. And accepting the limitations of your environment. As Eric Evans said in his book, don't fight your tools, don't fight your frameworks.
I mostly agree with your idea about static methods. But what about operations that depend of both arguments equally? For example Math.min or Math.max. Should we really have a 5.min(3)? It sounds counter intuitive to me. I think it is better to have a static method called min(3,5). In an ideal language, this would be a global function. Notice that since it has no global state, no testability is lost.
ReplyDeleteWouldn't the last change make it more difficult to promote a User to SuperUser?, I mean, wouldn't the viability of this change be dependant on stuff like this?
ReplyDeleteI cannot agree more. Static state is terrible! People often say that it is not the case, but once it bites you in the behind, you will never think the same again.
ReplyDeleteI have a question, what would be a possible solution to a global class that returns some state when a get() (yes, static) is called on it? I would love to refactor the code in such away that get() is no longer needed. Any advice would be greatly appreciated... this has been annoying me for a long long time.
I disagree with you in that I think static methods are just fine as long as they do not maintain global state. This is mainly due to the DRY principle.
ReplyDeleteGiven a function of two differently typed arguments, let's call them X and Y, it would be bad design to implement X(Y) and Y(X) in different places in your code as whenever X(Y) had to be updated, so would Y(X). This may seem like a corner case but many variations on this theme frequently occur in large projects.
That User/SuperUser/AgentUser thing is beautiful in theory, but hard to achieve in practice.
ReplyDeleteWhat if you can change the type of a user, from 'agent' to 'super'? Most languages won't let you do it. ORM frameworks (Hibernate) won't let you do it. At least not in a nice, clean way. Also, what about the 'composition over inheritance' principle?
About the static methods rant, how to avoid an explosion in the number of methods in basic classes, like string and number? String.toJDOMElementTree() would be a candidate?
I don't disagree with you, in that people could do much, much better.
It's just funny. People discuss design principles as if they were a cohesive, coherent, single body of absolute truth, when in reality most of them are disconnected, contradictory, context-specific rules, that are all correct individually, but nearly impossible to be fully followed together.
For example, how to maximize encapsulation of a class, without violating the 'S' in SOLID? Or, how to maximize reuse (DRY) without raising coupling, while keeping it simple?
What I'm trying to say is, to design is to make choices and to balance trade-offs. And accepting the limitations of your environment. As Eric Evans said in his book, don't fight your tools, don't fight your frameworks.
But, you should always try to do your best! :)