Encapsulation. Well-designed class - oop

Today I read a book and the author wrote that in a well-designed class the only way to access attributes is through one of that class methods. Is it a widely accepted thought? Why is it so important to encapsulate the attributes? What could be the consequences of not doing it? I read somewhere earlier that this improves security or something like that. Any example in PHP or Java would be very helpful.

Is it a widely accepted thought?
In the object-oriented world, yes.
Why is it so important to encapsulate the attributes? What could be the consequences of not doing it?
Objects are intended to be cohesive entities containing data and behavior that other objects can access in a controlled way through a public interface. If an class does not encapsulate its data and behavior, it no longer has control over the data being accessed and cannot fulfill its contracts with other objects implied by the public interface.
One of the big problems with this is that if a class has to change internally, the public interface shouldn't have to change. That way it doesn't break any code and other classes can continue using it as before.
Any example in PHP or Java would be very helpful.
Here's a Java example:
public class MyClass {
// Should not be < 0
public int importantValue;
...
public void setImportantValue(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("value cannot be < 0");
}
}
...
}
The problem here is that because I haven't encapsulated importantValue by making it private rather than public, anyone can come along and circumvent the check I put in the setter to prevent the object from having an invalid state. importantValue should never be less than 0, but the lack of encapsulation makes it impossible to prevent it from being so.

What could be the consequences of not
doing it?
The whole idea behind encapsulation is that all knowledge of anything related to the class (other than its interface) is within the class itself. For example, allowing direct access to attributes puts the onus of making sure any assignments are valid on the code doing the assigning. If the definition of what's valid changes, you have to go through and audit everything using the class to make sure they conform. Encapsulating the rule in a "setter" method means you only have to change it in one place, and any caller trying anything funny can get an exception thrown at it in return. There are lots of other things you might want to do when an attribute changes, and a setter is the place to do it.
Whether or not allowing direct access for attributes that don't have any rules to bind them (e.g., anything that fits in an integer is okay) is good practice is debatable. I suppose that using getters and setters is a good idea for the sake of consistency, i.e., you always know that you can call setFoo() to alter the foo attribute without having to look up whether or not you can do it directly. They also allow you to future-proof your class so that if you have additional code to execute, the place to put it is already there.
Personally, I think having to use getters and setters is clumsy-looking. I'd much rather write x.foo = 34 than x.setFoo(34) and look forward to the day when some language comes up with the equivalent of database triggers for members that allow you to define code that fires before, after or instead of a assignments.

Opinions on how "good OOD" is achieved are dime a dozen, and also very experienced programmers and designers tend to disagree about design choices and philosophies. This could be a flame-war starter, if you ask people across a wide varieties of language background and paradigms.
And yes, in theory are theory and practice the same, so language choice shouldn't influence high level design very much. But in practice they do, and good and bad things happen because of that.
Let me add this:
It depends. Encapsulation (in a supporting language) gives you some control over how you classes are used, so you can tell people: this is the API, and you have to use this. In other languages (e.g. python) the difference between official API and informal (subject to change) interfaces is by naming convention only (after all, we're all consenting adults here)
Encapsulation is not a security feature.

Another thought to ponder
Encapsulation with accessors also provides much better maintainability in the future. In Feanor's answer above, it works great to enforce security checks (assuming your instvar is private), but it can have much further reaching benifits.
Consider the following scenario:
1) you complete your application, and distribute it to some set of users (internal, external, whatever).
2) BigCustomerA approaches your team and wants an audit trail added to the product.
If everyone is using the accessor methods in their code, this becomes almost trivial to implement. Something like so:
MyAPI Version 1.0
public class MyClass {
private int importantValue;
...
public void setImportantValue(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("value cannot be < 0");
}
importantValue = newValue;
}
...
}
MyAPI V1.1 (now with audit trails)
public class MyClass {
private int importantValue;
...
public void setImportantValue(int newValue) {
if (newValue < 0) {
throw new IllegalArgumentException("value cannot be < 0");
}
this.addAuditTrail("importantValue", importantValue, newValue);
importantValue = newValue;
}
...
}
Existing users of the API make no changes to their code and the new feature (audit trail) is now available.
Without encapsulation using accessors your faced with a huge migration effort.
When coding for the first time, it will seem like a lot of work. Its much faster to type: class.varName = something vs class.setVarName(something); but if everyone took the easy way out, getting paid for BigCustomerA's feature request would be a huge effort.

In Object Oriente Programming there is a principle that is known as (http://en.wikipedia.org/wiki/Open/closed_principle):
POC --> Principle of Open and Closed. This principle stays for: a well class design should be opened for extensibility (inheritance) but closed for modification of internal members (encapsulation). It means that you could not be able to modify the state of an object without taking care about it.
So, new languages only modify internal variables (fields) through properties (getters and setters methods in C++ or Java). In C# properties compile to methods in MSIL.
C#:
int _myproperty = 0;
public int MyProperty
{
get { return _myproperty; }
set { if (_someVarieble = someConstantValue) { _myproperty = value; } else { _myproperty = _someOtherValue; } }
}
C++/Java:
int _myproperty = 0;
public void setMyProperty(int value)
{
if (value = someConstantValue) { _myproperty = value; } else { _myproperty = _someOtherValue; }
}
public int getMyProperty()
{
return _myproperty;
}

Take theses ideas (from Head First C#):
Think about ways the fields can misused. What can go wrong if they're not set properly.
Is everything in your class public? Spend some time thinking about encapsulation.
What fields require processing or calculation? They are prime candidates.
Only make fields and methods public if you need to. If you don't have a reason to declare something public, don't.

Related

NullObject Pattern: How to handle fields?

Suppose we have Book class which contains year_published public field. If I want to implement NullObject design pattern, I will need to define NullBook class which behaves same as Book but does not do anything.
Question is, what should be the behavior of NullBook when it's fields are being assigned?
Book book = find_book(id_value); //this method returns a NullBook instance because it cannot find the book
book.year_published = 2016; //What should we do here?!
The first thing you should do is to make your properties private.
class NullBook {
private year_published;
// OR solution2 private year_published = null;
public setYearPublished(year_published) {
this.year_published = null;
// OR solution2 do nothing!
}
}
You can also define the field private in the parent class, so the children will have to implement the setter to acces the field
class Book {
private year_published;
public setYearPublished(year_published) {
this.year_published = year_published;
}
}
class NullBook extends Book {
public setYearPublished(year_published) {
parent::setYearPublished(null);
}
}
Why use getters and setters?
https://stackoverflow.com/a/1568230/2377164
Thing is: patterns are about balancing. Yes, it is in general good practice to not return null, but to having else to return; but well: what is returned should still make sense!
And to a certain degree, I don't see how having a "NullBook" really helps with the design of your application. Especially as you allow access to various internal fields. You exactly asked the correct question: what should be the published year, or author, or ... of such a "NullBook"?!
What happens for example when some piece of code does a "lookup" on books from different "sources"; and then tries to sort those books on the published year. You sure don't want your NullBook to ever be part of such data.
Thus I fail to see the value in having this class, to the contrary: I see it creating a potential for "interesting" bugs; thus my answer is: step back and re-consider if you really need that class.
There are alternatives to null-replacing objects: maybe your language allows for Optionals; or, you rework those methods that could return null ... to return a collection/array of books; and in doubt: that list/array is simply empty.
Long story short: allowing other classes direct access to private fields is a much more of an import design smell; so you shouldn't be too focused on NullObjects, while giving up on such essential things as Information Hiding so easily on the other hand.

When is it considered good design to directly set property values on an object without the use of a setter?

This may not be the best kind of question suited to stackoverflow, but I'm only after an answer that best describes why programmers sometimes don't use setters/getters for properties, e.g. in the case of property injection (DI).
Consider this example...
class Test
{
public propertyA;
protected propertyB;
public function setPropertyB(val)
{
// do some logic to validate 'val'
this.propertyB = val;
}
public function getPropertyB()
{
return this.propertyB;
}
}
Why would you choose the style of directly setting propertyA:
var Test = new Test();
Test.propertyA = 1;
Over the setter option for propertyB:
var Test = new Test();
Test.setPropertyB(1);
I always use the setter/getter approach, but I have seen some pretty established frameworks using the propertyA approach interspersed with the propertyB approach. What benefits do we have using this method?
Why you might not care about encapsulation:
You might be throwing away the project 15 minutes later.
You might have found getters/setters to be bottlenecks for your CPU-bound code, causing you to optimize for performance instead of design.
The instance field might be immutable and read-only, so there might be no danger in exposing it.
You're too lazy to write getters/setters.
You should use getters and setters because they allow you to control the interface to your objects.
For example, let's say I have a bank account class in a Java application:
class BankAccount {
private int balance;
BankAccount() {
balance = 0;
}
public void deposit(int amount) {
balance = balance + amount;
}
public void withdraw(int amount) {
balance = balance - amount;
}
}
When my software needs to alter a bank account's balance through deposits and withdrawals, it calls the appropriate methods.
Now, along comes some sneaky individual who manages to figure out that they can increase their bank balance by telling their internet banking software to withdraw negative amounts of money. I can fix this bug by adding a precondition to the withdraw method, and the bug goes away.
If the balance field was instead public, and a whole bunch of classes were just manipulating it's value arbitrarily, those classes would now need to be changed. If some of those external classes were written by third parties, then we're looking at a whole lot of pain to get the bug fixed.
Why would you use public fields? In the general case, you probably shouldn't. Some languages allow you to have a field scoped as public, then if you need to add a getter/setter later on you can do so without changing your object's interface (I believe C# does this, but correct me if I'm wrong).

Are there adverse effects of passing around objects rather than assigning them as members of a class

I have a habit of creating classes that tend to pass objects around to perform operations on them rather than assigning them to a member variable and having operations refer to the member variable. It feels much more procedural to me than OO.
Is this a terrible practice? If so, what are the adverse effects (performance, memory consumption, more error-prone)? Is it simply easier and more closely aligned to OO principles like encapsulation to favour member variables?
A contrived example of what I mean is below. I tend to do the following;
public class MyObj()
{
public MyObj() {}
public void DoVariousThings(OtherObj oo)
{
if (Validate(oo))
{
Save(oo);
}
}
private bool Validate(OtherObj oo)
{
// Do stuff related to validation
}
private bool Save(OtherObj oo)
{
// Do stuff related to saving
}
}
whereas I suspect I should be doing the following;
public class MyObj()
{
private OtherObj _oo;
public MyObj(OtherObj oo)
{
_oo = oo;
}
public void DoVariousThings()
{
if (Validate())
{
Save();
}
}
private bool Validate()
{
// Do stuff related to validation with _oo
}
private bool Save()
{
// Do stuff related to saving with _oo
}
}
If you write your programs in an object oriented language, people will expect object oriented code. As such, in your first example, they would probably expect that the reason for making oo a parameter is that you will use different objects for it all the time. In your second example, they would know that you always use the same instance (as initialized in the constructor).
Now, if you use the same object all the time, but still write your code like in your first example, you will have them thoroughly confused. When an interface is well designed, it should be obvious how to use it. This is not the case in your first example.
I think you already answered your question yourself, you seem to be aware of the fact that the 2nd approach is more favorable in general and should be used (unless there are serious reasons for the first approach).
Advantages that come to my mind immediately:
Simplified readability and maintainability, both for you and for others
Only one entry point, therefore only needing to checking for != null etc.
In case you want to put that class under test, it's way easier, i.e., getting something like this (extracting interface IOtherObj from OtherObj and working with that):
public MyObj (IOtherObj oo)
{
if (oo == null) throw...
_oo = oo;
}
Talking of the adverse effects of your way, there are none, but only if you are keeping the programs and the code to yourself,, what are you doing is NOT a standard thing, say, if after some time, you start to work making libraries and code that may be used by others also, then it is a big problem. The may pass any foo object and hope that it would work.
you have to validate the object before passing it and if the validation fails do things accordingly, but if u use the standard OOP way, there is no need for validation or taking up the cases where an inappropriate type object is pass,
In a nutshell, your way is bad for :
1. code re-usability.
2. you have to handle more exceptions.
3. okay, if u r keeping things to urself, otherwise, not a good practice.
hope, it cleared some doubt.

Is there a commonly used OO Pattern for holding "constant variables"?

I am working on a little pinball-game project for a hobby and am looking for a pattern to encapsulate constant variables.
I have a model, within which there are values which will be constant over the life of that model e.g. maximum speed/maximum gravity etc. Throughout the GUI and other areas these values are required in order to correctly validate input. Currently they are included either as references to a public static final, or just plain hard-coded. I'd like to encapsulate these "constant variables" in an object which can be injected into the model, and retrieved by the view/controller.
To clarify, the value of the "constant variables" may not necessarily be defined at compile-time, they could come from reading in a file; user input etc. What is known at compile time is which ones are needed. A way which may be easier to explain it is that whatever this encapsulation is, the values it provides are immutable.
I'm looking for a way to achieve this which:
has compile time type-safety (i.e. not mapping a string to variable at runtime)
avoids anything static (including enums, which can't be extended)
I know I could define an interface which has the methods such as:
public int getMaximumSpeed();
public int getMaximumGravity();
... and inject an instance of that into the model, and make it accessible in some way. However, this results in a lot of boilerplate code, which is pretty tedious to write/test etc (I am doing this for funsies :-)).
I am looking for a better way to do this, preferably something which has the benefits of being part of a shared vocabulary, as with design patterns.
Is there a better way to do this?
P.S. I've thought some more about this, and the best trade-off I could find would be to have something like:
public class Variables {
enum Variable {
MaxSpeed(100),
MaxGravity(10)
Variable(Object variableValue) {
// assign value to field, provide getter etc.
}
}
public Object getVariable(Variable v) { // look up enum and get member }
} // end of MyVariables
I could then do something like:
Model m = new Model(new Variables());
Advantages: the lookup of a variable is protected by having to be a member of the enum in order to compile, variables can be added with little extra code
Disadvantages: enums cannot be extended, brittleness (a recompile is needed to add a variable), variable values would have to be cast from Object (to Integer in this example), which again isn't type safe, though generics may be an option for that... somehow
Are you looking for the Singleton or, a variant, the Monostate? If not, how does that pattern fail your needs?
Of course, here's the mandatory disclaimer that Anything Global Is Evil.
UPDATE: I did some looking, because I've been having similar debates/issues. I stumbled across a list of "alternatives" to classic global/scope solutions. Thought I'd share.
Thanks for all the time spent by you guys trying to decipher what is a pretty weird question.
I think, in terms of design patterns, the closest that comes to what I'm describing is the factory pattern, where I have a factory of pseudo-constants. Technically it's not creating an instance each call, but rather always providing the same instance (in the sense of a Guice provider). But I can create several factories, which each can provide different psuedo-constants, and inject each into a different model, so the model's UI can validate input a lot more flexibly.
If anyone's interested I've came to the conclusion that an interface providing a method for each psuedo-constant is the way to go:
public interface IVariableProvider {
public int maxGravity();
public int maxSpeed();
// and everything else...
}
public class VariableProvider {
private final int maxGravity, maxSpeed...;
public VariableProvider(int maxGravity, int maxSpeed) {
// assign final fields
}
}
Then I can do:
Model firstModel = new Model(new VariableProvider(2, 10));
Model secondModel = new Model(new VariableProvider(10, 100));
I think as long as the interface doesn't provide a prohibitively large number of variable getters, it wins over some parameterised lookup (which will either be vulnerable at run-time, or will prohibit extension/polymorphism).
P.S. I realise some have been questioning what my problem is with static final values. I made the statement (with tongue in cheek) to a colleague that anything static is an inherently not object-oriented. So in my hobby I used that as the basis for a thought exercise where I try to remove anything static from the project (next I'll be trying to remove all 'if' statements ;-D). If I was on a deadline and I was satisfied public static final values wouldn't hamstring testing, I would have used them pretty quickly.
If you're just using java/IOC, why not just dependency-inject the values?
e.g. Spring inject the values via a map, specify the object as a singleton -
<property name="values">
<map>
<entry> <key><value>a1</value></key><value>b1</value></entry>
<entry> <key><value>a2</value></key><value>b3</value></entry>
</map>
</property>
your class is a singleton that holds an immutable copy of the map set in spring -
private Map<String, String> m;
public String getValue(String s)
{
return m.containsKey(s)?m.get(s):null;
}
public void setValues(Map m)
{
this.m=Collections.unmodifiableMap(m):
}
From what I can tell, you probably don't need to implement a pattern here -- you just need access to a set of constants, and it seems to me that's handled pretty well through the use of a publicly accessible static interface to them. Unless I'm missing something. :)
If you simply want to "objectify" the constants though, for some reason, than the Singleton pattern would probably be called for, if any; I know you mentioned in a comment that you don't mind creating multiple instances of this wrapper object, but in response I'd ask, then why even introduce the sort of confusion that could arise from having multiple instances at all? What practical benefit are you looking for that'd be satisfied with having the data in object form?
Now, if the values aren't constants, then that's different -- in that case, you probably do want a Singleton or Monostate. But if they really are constants, just wrap a set of enums or static constants in a class and be done! Keep-it-simple is as good a "pattern" as any.

avoiding if statements

I was thinking about object oriented design today, and I was wondering if you should avoid if statements. My thought is that in any case where you require an if statement you can simply create two objects that implement the same method. The two method implementations would simply be the two possible branches of the original if statement.
I realize that this seems extreme, but it seems as though you could try and argue it to some extent. Any thoughts on this?
EDIT
Wow that didn't take long. I suppose this is way too extreme. Is it possible to say though, that under OOP you should expect way less if statements?
SECOND EDIT
What about this: An object that determines its method implementation based on its attributes. That is to say you can implement someMethod() in two ways and specify some restrictions. At any point an object will route to the correct method implementation based on its properties. So in the case of if(x > 5) just have two methods that rely on the x attribute
I can tell you one thing. No matter what people say, thinking about simplifying and eliminating unnecessary branching is a sign of you maturing as a software developer. There are many reasons why branching is bad, testing, maintenance, higher rate of bugs and so on. This is one of the things I look for when interviewing people and is an excellent indicator how mature they are as a developer. I would encourage you to keep experimenting, simplifying your code and design by using less conditions. When I did this switch I found much less time debugging my code, it simply worked, then when I had to change something, changes were super easy to make since most of the code was sequential. Again I would encourage you 100% to keep doing what you are doing no matter what other people say. Keep in mind most developers are working and thinking at much lower level and just follow the rules. So good job bringing this up.
Explain how to implement the following without an if statement or ternary logic:
if ( x < 5 ) {
x = 0
} else {
print x;
}
Yes its true that often complex conditionals can be simplified with polymorphishm. But its not useful all the time. Go read Fowler's Refactoring book to get an idea of when.
http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html
Completely eliminating if statements is not realistic and I don't think that is what Ori is suggesting. But they can often be replaced using polymorphism. (And so can many switch statements).
Francesco Cirillo started the Anti-If Campaign to raise awareness of this issue. He says:
Knowing how to use objects lets developers eliminate IFs based on type, those that most often compromise software's flexibility and ability to evolve.
You or your team can also join the campaign.
One of my teacher used to say that. I tend to think that people being so dogmatic about that kind of thing usually don't program for a living.
Avoiding If Statement: There are many ways to do, one of them is below:
int i=0;
if(i==1)
{
//Statement1
}
if(i==2)
{
//Statement2
}
if(i==3)
{
//Statement3
}
if(i==4)
{
//Statement4
}
Using Dictionary and delegate:
delegate void GetStatement ();
Dictionary<int,GetStatement > valuesDic=new Dictionary<int,GetStatement >();
void GetStatement1()
{
//Statement1
}
void GetStatement2()
{
//Statement2
}
void GetStatement3()
{
//Statement3
}
void GetStatement4()
{
//Statement4
}
void LoadValues()
{
valuesDic.Add(1,GetStatement1);
valuesDic.Add(2,GetStatement2);
valuesDic.Add(3,GetStatement3);
valuesDic.Add(4,GetStatement4);
}
Replacing If Statement:
int i=0;
valuesDic[i].Invoke();
Have a look at the Anti-If Campaign The idea is not to replace every single if in your application with the Strategy or State Pattern. The idea is that when you have complex branching logic especially based on something like an enumeration, you should look to refactoring to the Strategy Pattern.
And that case you can remove the if all together by using a Factory. Here is a relatively straightforward example. Of course as I said in a real case, the logic in your strategies would be a bit more complex than just printing out "I'm Active".
public enum WorkflowState
{
Ready,
Active,
Complete
}
public interface IWorkflowStrategy
{
void Execute();
}
public class ActiveWorkflowStrategy:IWorkflowStrategy
{
public void Execute()
{
Console.WriteLine("The Workflow is Active");
}
}
public class ReadyWorkflowStrategy:IWorkflowStrategy
{
public void Execute()
{
Console.WriteLine("The Workflow is Ready");
}
}
public class CompleteWorkflowStrategy:IWorkflowStrategy
{
public void Execute()
{
Console.WriteLine("The Workflow is Complete");
}
}
public class WorkflowStrategyFactory
{
private static Dictionary<WorkflowState, IWorkflowStrategy> _Strategies=
new Dictionary<WorkflowState, IWorkflowStrategy>();
public WorkflowStrategyFactory()
{
_Strategies[WorkflowState.Ready]=new ReadyWorkflowStrategy();
_Strategies[WorkflowState.Active]= new ActiveWorkflowStrategy();
_Strategies[WorkflowState.Complete] = new CompleteWorkflowStrategy();
}
public IWorkflowStrategy GetStrategy(WorkflowState state)
{
return _Strategies[state];
}
}
public class Workflow
{
public Workflow(WorkflowState state)
{
CurrentState = state;
}
public WorkflowState CurrentState { get; set; }
}
public class WorkflowEngine
{
static void Main(string[] args)
{
var factory = new WorkflowStrategyFactory();
var workflows =
new List<Workflow>
{
new Workflow(WorkflowState.Active),
new Workflow(WorkflowState.Complete),
new Workflow(WorkflowState.Ready)
};
foreach (var workflow in workflows)
{
factory.GetStrategy(workflow.CurrentState).
Execute();
}
}
}
In some ways this can be a good idea. Swiching on a type field inside an object is usually a bad idea when you can use virtual functtions instead. But the virtual function mechanism is in no way intended to replace the if() test in general.
How do you decide which object's method to use without an if statement?
It depends on what the original statement is comparing. My rule of thumb is that if it's a switch or if testing equality against an enumeration, then that's a good candidate for a separate method. However, switch and if statements are used for many, many other kinds of tests -- there's no good way to replace the relational operators (<, >, <=, >=) with specialized methods, and some kinds of enumerated tests work much better with standard statements.
So you should only replace ifs if they look like this:
if (obj.Name == "foo" || obj.Name == "bar") { obj.DoSomething(); }
else if (obj.Name == "baz") { obj.DoSomethingElse(); }
else { obj.DoDefault(); }
In answer to ifTrue's question:
Well, if you have open classes and a sufficiently strong dependent type system, it's easy, if a bit silly. Informally and in no particular language:
class Nat {
def cond = {
print this;
return this;
}
}
class NatLessThan<5:Nat> { // subclass of Nat
override cond = {
return 0;
}
}
x = x.cond();
(continued...)
Or, with no open classes but assuming multiple dispatch and anonymous classes:
class MyCondFunctor {
function branch(Nat n) {
print n;
return n;
}
function branch(n:NatLessThan<5:Nat>) {
return 0;
}
}
x = new MyCondFunctor.branch(x);
Or, as before but with anonymous classes:
x = new {
function branch(Nat n) {
print n;
return n;
}
function branch(n:NatLessThan<5:Nat>) {
return 0;
}
}.branch(x);
You'd have a much easier time if you refactored that logic, of course. Remember that there exist fully Turing-complete type systems.
Assume we have conditional values.
public void testMe(int i){
if(i=1){
somevalue=value1;
}
if(i=2){
somevalue=value2;
}
if(i=3){
somevalue=value3;
}
}
//**$$$$$you can replace the boring IF blocks with Map.$$$$$**
// ============================================================
Same method would look like this:
--------------------------------
public void testMe(int i){
Map<Integer,String> map = new HashMap<Integer,String>();
map.put(1,value1);
map.put(2,value2);
map.put(3,value3);
}
This will avoid the complicated if conditions.
You can use simliar solution when using factory patterns for loading classes.
public void loadAnimalsKingdom(String animalKingdomType)
if(animalKingdomType="bird"){
Bird b = new Bird();
}
if(animalKingdomType="animal"){
Animal a= new Animal();
}
if(animalKingdomType="reptile"){
Reptile r= new Reptile();
}
}
Now using map :
public void loadAnimalsKingdom(String animalKingdomType)
{
Map <String,String> map = new HashMap<String,String>();
map.put("bird","com.animalworld.Bird.Class");
map.put("animal","com.animalworld.Animal.Class");
map.put("reptile","com.animalworld.Reptile.Class");
map.get(animalKingdomType);
***Use class loader to load the classes on demand once you extract the required class from the map.***
}
Like the solution? Give thumbs-up. - Vv
Creating a whole new class for an else, while technically doable, would likely result in code that is hard to read, maintain, or even prove correct.
That's an interesting idea. I think that you could theoretically do this, but it would be an enormous pain in a language not specifically designed to support it. I certainly don't see any reason to.
I think what he is saying or what he means to say is that he thinks it is best to avoid over-abuse of "tagging" and adding custom functionality to a class by several if statements when it better makes sense to subclass or rethink the object hierarchy.
It is quite extreme. Doing what you are suggesting would cause a lot of needless code duplication, unless the entire function was completely different, based on a single surrounding if; and if so, that if should probably have been on the other side of the method invocation.
If-statements certainly have their place in object-orient design.
Surely some form of comparison needs to be made regardless of what you do? In the end ... sure you can avoid if statements but you'd be producing code that is IDENTICAL to the code using an if statement.
Someone correct me if im wrong but I can't think of a time where you could get any win form doing this.
I think applying that argument to the idea of every if statement is pretty extreme, but some languages give you the ability to apply that idea in certain scenarios.
Here's a sample Python implementation I wrote in the past for a fixed-sized deque (double-ended queue). Instead of creating a "remove" method and having if statements inside it to see if the list is full or not, you just create two methods and reassign them to the "remove" function as needed.
The following example only lists the "remove" method, but obviously there are "append" methods and the like also.
class StaticDeque(collections.deque):
def __init__(self, maxSize):
collections.deque.__init__(self)
self._maxSize = int(maxSize)
self._setNotFull()
def _setFull(self):
self._full = True
self.remove = self._full_remove
def _setNotFull(self):
self._full = False
self.remove = self._not_full_remove
def _not_full_remove(self,value):
collections.deque.remove(self,value)
def _full_remove(self,value):
collections.deque.remove(self,value)
if len(self) != self._maxSize and self._full:
self._setNotFull()
In most cases it's not that useful of an idea, but sometimes it can be helpful.
I will say the answer is vaguely yes-ish. Especially when the language allows some heavy duty functional programming (ie C#, F#, OCaml).
A component that contains 2 if statements strongly couples two business rules so break it up.
Take that as a very general rule of thumb but I would agree. If you have a bunch of if statements, maybe you should think about another approach.
If-statements are pretty core to programming so, in short, you cannot sensibly avoid them.
However, a key goal in OOP--in fact, one of the "pillars"--is encapsulation. The old "encapsulate what varies" rule helps you remove those troublesome if and case statements where you are trying to account for every option in your object. A better solution to dealing with branches, special cases, etc. is to use something like the "Factory" design pattern (Abstract Factory or Factory Method--depending on needs, of course).
For example, rather than having your main code loop check which OS your using with if statements then branch to create GUI windows with different options for each OS, your main code would create an object from the factory, which use the OS to determine which OS-specific concrete object to make. In doing this you are taking the variations (and the long if-then-else clauses) out of your main code loop and letting the child objects handle it--so the next time you need to make a change such as supporting a new OS, you merely add a new class from the factory interface.
I've been following the anti-if talk lately and it does sound like extreme / hyperbolic rhetoric to me. However I think there is truth in this statement: often the logic of an if statement can be more appropriately implemented via polymorphism. I think it is good to keep that in mind every time you right an if statement. That being said, I think the if statement is still a core logic structure, and it should not be feared or avoided as a tenet.
My two bits here of what I understand of the Object Oriented approach -
First, what objects in a program should be intuitive. That is, I should not try to create a 'Arithmatic' class to provide mathematical functions. This is an abuse of OOD.
Second and this is a very strong opinion of mine. It should not be called Object Oriented design but Object and Method Oriented design! If the method names of the objects are themselves not intuitive then inherited objects might end up reimplementing the methods already available.
Object Oriented approach, according to me, is not a replacement for the Procedural approach. Rather it is mainly for two main reasons for the creators of the language -
Better capability of scoping of variables.
Better capability of garbage collection rather than having too many global variables.
I agree with Vance that the IF is not good, because it increases the conditional complexity and should be avoided as possible.
Polymorphism is a totally viable solution at condition it's used to make sense and not to "Avoid If".
A side note that does not fit to your OOP requirements but the Data Oriented approach also tends to avoid the branching.
You must understand what (x > 5) really mean. Assuming that x represents a number, then it basically "classifies" all numbers greater than five. So the code would look like this in a language with python syntax:
class Number(Object):
# ... Number implementation code ... #
def doSomething():
self = 0
return self
def doSomethingElse():
pass
class GreaterThan5(Number):
def doSomething():
print "I am " + self
def doSomethingElse():
print "I like turtles!"
Then we could run code like the following:
>>> type(3)
<class Number>
>>> type(3+3)
<class GreaterThan5>
>>> 3.doSomething()
0
>>> (3 + 3).doSomething()
I am 6
>>> (7 - 3).doSomethingElse()
>>>
The automatic type conversion here is important. As far as I am aware, none of the languages today allow you to mess with integers this much.
In the end, you can do in your code whatever. As long as the people reading it can understand immediately. So the polymorphic dispatch on integers or anything unordinary must have really good reasoning behind it.