Explanation of this "bad programming habit"? [closed] - oop

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
I'm learning OOP and I found that there is a bad programming habit of creating
wrapper classes for information on one side and classes with methods that handle the first on the other, but I don't understand this concept so I'm asking for some explanation and an example if possible.
Thanks in advance

I think you seem to be getting at situations where the methods would be better off inside the information class - that the two should be merged and class that acts on the information should also store it.
class CoordinatePair
{
float x, y;
public Coordinate(float xIn, float yIn) {x = xIn; y = yIn;}
public getX() {return x;}
public getY() {return y;}
}
class CoordinateTools
{
public CoordinatePair add(Coordinate a, Coordinate b)
{
return new CoordinatePair(a.getX() + b.getX(), a.getY() + b.getY());
}
public float dotProduct(Coordinate a, Coordinate b)
{
returna a.getX() * b.getX() + a.getY() * b.getY());
}
}
Could be better done with: (or alternatively overloaded operators, at the very least a static tools class)
class CoordinatePair
{
float x, y;
public Coordinate(float xIn, float yIn) {x = xIn; y = yIn;}
public getX() {return x;}
public getY() {return y;}
public CoordinatePair sumWith(CoordinatePair other) {//body}
public float dotProductWith(CoordinatePair otheR) {//body}
}
This example is kind of trivial but you hopefully could see it getting worse with more involved stuff.

What you're describing is a "dumb model", and it's a pretty minor problem. Keep your eyes out for code that hits every field on your information classes, or starts reaching into its datastructures to change or read them - especially if you find yourself doing similar operations in multiple parts of the application. When you catch any of those, try moving that work into methods on the information classes.
A good way to track the second type of problem is the one dot rule - if you find yourself calling methods of a class inside another class, the first class should probably handle the operation in a method.

I would say: it depends.
There are some situations, where separating data from behaviors will be the best solution, for example in data transfer objects or in domain entities. This separation is also useful when designing algorithms - have a look at visitor pattern or how STL algoritms are designed.
Generally, Single responsibility principle is important here. If your object is trying to do a lot of different, logically independent operations, separating those operations from the data can be a good solution.

Related

Loading from database - inside or outside class? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I've seen different ways of loading an object to and fro a database, with two common ones as shown below. Which one is better, and why?
Method 1: This includes defining two member methods for a class, load(id) and save(). These methods are called on instances of the class. For example,
class Wheel{
double diameter;
string tag;
public void Load(int id){
var result = ... // database query
this.diameter = result['diameter'];
this.tag = result['tag'];
}
public void Save(){
... // database query to update row
}
}
Wheel johnWheel = new Wheel();
johnWheel.Load(5); // In this case John's wheel has a row id of 5 in the database
Method 2: A utility method which loads/saves an object directly:
class DBUtils{
public static Wheel LoadWheel(int id){
var result = ... // database query
Wheel w = new Wheel();
w.setDiameter(result['diameter']);
w.setTag(result['tag']);
}
public static void SaveWheel(Wheel wheel){
...// Update DB
}
}
I ask because the notion of a 'wheel' itself does not include functions which loads and saves it from a database, so perhaps method 1 would be considered bad OOP design.
Both seem a bit off...
Method 1
For one thing, Load() should be a static factory in this case. This usage is a bit obtuse:
Wheel johnWheel = new Wheel();
johnWheel.Load(5);
Between those two lines of code, what is johnWheel? Is it in anything approaching a valid state? If not, then it seems like its construction is a little broken. OO principles would suggest encapsulating that into a single operation rather than expecting consuming code to perform multiple sequential operations every time. If it's a static factory, the usage is simpler:
Wheel johnWheel = Wheel.Load(5);
Method 2
This one is more of a naming concern than a structure concern. DBUtils? That's going to turn into a dumping ground for unrelated functionality quickly. You want to avoid that. How about something like this?:
class WheelRepository
{
public static Wheel Get(int id)
{
// ...
}
public static void Save(Wheel wheel)
{
// ....
}
}
As an object (this is still OOP after all), a WheelRepository represents (and therefore encapsulates) very specific functionality whereas a DBUtils doesn't.
Conclusion
I generally prefer method 2 in a structural sense, because the business object (Wheel) shouldn't know anything about the database (WheelRepository). The former is a core portable business concern, the latter is a periphery infrastructure concern. My only caveat is that I'd recommend standard patterns for improving method 2, such as a combination of the Repository Pattern and the Unit Of Work pattern, for example.
You should create a separate class that handles database connections and the creation/destruction of these connections. That way, the wheel is a separate entity from the database it is using.
Go with method 2.
I would go with Method 2 (like laiello proposed). I would however not name the class DbUtils but more something like WheelDao or WheelRepository (if for instance your Wheel class is an Root entity in your domain model).
If however you go with Method 1 the load(id) method should be static. Since it is not called on a particular instance of an object but it rather produces a new instance of an object. This is unlike the save() method for which it is correct to be called on a specific instance of Wheel.

Is it bad OOP practice to subclass MANY classes from a base class?

I'm relatively new to this site so if I am doing something wrong when it comes to posting questions and whatnot please let me know so I can fix it for next time.
I'm curious as to whether or not it is bad OOP practice to subclass multiple classes from a single base class. That probably doesn't quite make sense so I'm going to elaborate a little bit.
Say for instance you are designing a game and you have several different monsters you might come across. The approach I would take is to have a base abstract class for just a general monster object and then subclass all of the specific types of monsters from the base class using a new class.
One of my instructors told me that you shouldn't rely on inheritance in this case because the number of monsters will continue to grow and grow and the number of classes will increase to a point where it is hard to keep track of all of them and thus yo will have to recompile the program with every new class added in the future.
I don't understand why (or even if) that's a bad thing. If anybody could help me understand where my professor is coming from that would be much appreciated.
Thanks!
If monsters are very similar, in that the only differences are (for example) their name, how much damage they impart, what color they are, etc., then these differences which can be reflected in a field (in values), may make sub-classing unnecessary.
If, however, you have monsters that are fundamentally different from others, such that it is necessary to have very different methods and logic, and more specifically, differences that cannot be reflected in fields, then a sub-class SpecialMonster may be necessary.
But again, even SpecialMonster may not need to be sub-classed by individual monster types, as it's fields may be enough to distinguish between them.
While it's legal to have a million sub-classes of specific monster types, you don't want to take care of all that duplicate code when it could simply be expressed in the fields of new Monster instances, such as
new Monster("Goob", WakeTime.NOCTURNAL, 35, new Weapon[]{sword, hammer, knittingNeedle});
new Monster("Mister Mxyzptlk", WakeTime.ANYTIME, 71, new Weapon[]{sword, mindMeld, cardboardCutter});
There is an alternative, where you do have a lot of classes, but you don't impose them onto your users, and you don't clutter up your API/JavaDoc with them. If your Monster happens to be an abstract class
public abstract class Monster {
private final String name;
...
public Monster(String name, int default_damage, WakeTime wake_time, Weapon[] weapons) {
this.name = name;
...
}
public String getName() {
return name;
}
...
public abstract int getDamage(int hit_strength);
}
Then you could have a Monster convenience creator like this:
/**
<P>Convenience functions for creating new monsters of a specific type.</P>
**/
public class NewMonsterOfType {
private NewMonsterOfType() {
throw new IllegalStateException("Do not instantiate.");
}
/**
<P>Creates a new monster that is nocturnal, has 35-default-damage, and whose weapens are: sword, hammer, knittingNeedle.</P>
**/
public static final GOOB = new GoobMonster();
/**
<P>Creates a new monster that can be awake at any time, has 71-default-damage, and whose weapens are: sword, mindMeld, cardboardCutter.</P>
**/
public static final MISTER_MXYZPTLK = new MisterMxyzptlkMonster();
}
class GoobMonster extends Monster {
public GoobMonster() {
super("Goob", WakeTime.NOCTURNAL, 35, new Weapon[]{sword, hammer, knittingNeedle});
}
public int getDamage(int hit_strength) {
return (hit_strength < 70) ? getDefaultDamage() : (getDefaultDamage() * 2);
}
}
class MisterMxyzptlkMonster extends Monster {
public GoobMonster() {
super("Mister Mxyzptlk", WakeTime.ANYTIME, 71, new Weapon[]{sword, mindMeld, cardboardCutter});
}
public int getDamage(int hit_strength) {
return (hit_strength < 160) ? getDefaultDamage() + 10 : (getDefaultDamage() * 3);
}
}
In order for these private (actually package-protected) classes to not show up in you JavaDoc, you need to set its access to something either protected or public.
Inheritance is quite natural in your scenario as all the specific monsters ARE base monsters as well :). I'd actually use inheritance a lot here, since probably specific monsters do have specific behaviour that would have to be overriden. MonsterA might move by crawling while MonsterB might move by flying. The base AMonster would have an abstract Move() method , implemented by those sub types.
This isn't a final answer, it really much depends on the game needs, however, in simplified form, inheritance makes sense here. The number of monster types might continue to grow, but really, are they all the same? The monster design is just based on grouping together some predefined data/behaviour? The game is quite trivial then...
I really get the impression your instructor doesn't code games for a living (me neither, although I did make a game some time ago), but his explanation why you shouldn't use inheritance is way too simplified. The number of defined classes is never an issue in an app, the more the better IF the Single Responsibility Principle is respected.
About you have to recompile your app.... yeah, when you fix a bug you have to recompile it too. IMO, the reasons he gave to you aren't valid for this scenario. He needs to come up with much better arguments.
In the mean time, go for inheritance.
Theoretical question needs theoretical answer :).
It is not just bad, it is pointless. You should have a LIMITED number of "base" classes that inherits from other classes, and those classes should be composed from other classes (vide favour composition versus inheritance).
So as complexity grows the number of classes that base classes are composed from should grows. Not number of base classes itself.
It is like in the industry. If you see machines for instance, they are really composed from large quantity of small parts, and some of those small parts are the same in different machines. When yo designing new machine you do not order new unique "base" part for it just to have a name for your new machine. You use parts existing on a market and you designing some new parts (not "base") only if you cannot find existing counterparts...

is there a way to easily remember what instantiation, class, object of class [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
A lot of books use the word in their definition of what the word means (e.g a is an instance of b).
Maybe it's just me, but when I read a definition and the definition uses a different form of the word in its definition, it doesn't help much.
What is a class?
Anyone have a clear definition/explanation of instantiation?
I think I know what object is: it is when a class is process into the computer memory (this is when it becomes an "object" right?)
A class is simply a definition of how an object/instance will be structured. It's a blueprint. For example, this is a Person class:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Now, if we want to work with objects/instances of Person, we create them by instantiating them:
Person geddy = new Person();
Person alex = new Person();
Now we have two instances of Person (geddy, alex). And we can do stuff with them, like set their properties:
geddy.FirstName = "Geddy";
geddy.LastName = "Lee";
alex.FirstName = "Alex";
alex.LastName = "Lifeson";
Person is, and will always be, the class, or blueprint that defines the actual instances (geddy, alex).
Wikipedia quotes an excellent definition of an object:
"An object is the composition of nouns (like data, such as numbers, strings, or variables) and verbs (like actions, such as functions)"
An object is a concrete realization of a class which defines a template for the creation of objects.
A class is like a recipe. You cannot eat a recipe can you? But you can eat an instance of the recipe which is a result of following the instructions of making that recipe (say a chocolate cake).

Encapsulation. Well-designed class

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.

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.