As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Is it better to use constructors with parameters to initialize the members of a class or do that indirectly using setter functions? I did not get a clear answer on this question so far. Any insights would be appreciated.
It is almost certainly a matter of design choice or sometimes style. I would consider a number of things:
Would constructing an object without setting the member variables leave the class in an invalid state? If so, you'll need your constructor to take valid values for those members. Otherwise, you should be able to provide useful defaults.
Would setting individual members of variables violate a class invariant? If so, they should not have their own setters.
Is the user of this class likely to want to modify individual members? If so, then setters may be appropriate.
Does it make conceptual sense to be able to change individual members of an object? I would argue that it makes no sense to be able to change a Person's date of birth. However, you could argue that changing a Person's name does make sense. It depends. Do you consider a Person whose name has changed to be a different Person in your system?
Can you group setters together to be more useful? Instead of Rectangle::setX(int) and Rectangle::setY(int), does Rectangle::setPosition(int,int) make more sense? Perhaps even Rectangle::setPosition(Point) is better.
In any case, a class whose full set of members are exposed through individual setters and getters is usually a code smell.
The one thing you want to avoid is having an object that isn't complete. If you can supply sensible defaults for every parameter then it's OK to skip setting them in the constructor, otherwise you really should put them there.
Naturally there's no reason you can't do both.
It depends. Certainly use constructor parameters where the object doesn't make sense without a valid class member - for example, scoped smart pointers, or an ofstream's filename.
explicit ofstream ( const char * filename, ios_base::openmode mode = ios_base::out );
Use additional parameters sparingly, and provide default values wherever possible.
However, don't add so many constructor parameters that the order becomes impossible to remember, or if there's a chance of dangerous confusion, such as this.
Person(std::string firstname, std::string lastname, std::string title, std::string occupation,
std::string address, std::string telephone, int age, std::string creditcard, time_t birthday)
Related
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Programming languages like C# or Java feature static methods, despite being heavily object oriented.
I'm aware that there are many cases where static methods are used for performance or convenience reasons, but i can't stop wondering if there exist actual coding problems which could not be solved without the use of static methods.
I think that some of the common cases which would be named here could be just "normal" methods, instead of being static, like:
main: The purpose of the main-method is the creation of the very first running thread of the program and starting it. So this might as well just an object derived from a Thread class
Loggers: Logger implementations often use static methods. I don't see the point in that as i might want to exchange a logger for another on with an identical interface
Math: Math functions really seem to be a perfect candidate for static methods at first sight, but there might be cases where you might want to exchange your math library transparently for another one (i.e. if you need more performance on the sin() function you might want to use an implementation with a faster, less precise algorithm if precision is not critical for your application)
Singletons: Are considered bad practice by many. If only one instance is necessary you might think about actually creating only one instance.
So, what might be cases where static methods are really absolutely needed?
IMO, Static methods are needed while defining factories to create objects of different sub types of a given type where the choice of sub type is dependent on the inputs to this static factory method and is hidden from the client.
Your Logger example actually falls under this category where the actual logger is decided based on the package/class it is needed (ofcourse the other factory methods on Logger take other parameters to decide on the appropriate Logger instance to be returned).
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I have two buttons that each can perform two different implementations (whether selected or not), so that's 4 possible implementations in total. After coding it all out, I noticed I had 20+ lines of code for each implementation and only 1 or 2 variables were different in each. I decided I want to clean this up and have each implementation call separate, smaller methods and pass the inconsistent variables as parameters.
I figure this is a better practice b/c I'm reusing code. However, in one of my methods I have to pass 5 different arguments implement the method with correct conditions.
Is having this many parameters in a method a bad practice?
Having many parameters is not necessary a bad thing.
There are patterns that create a class to group all the parameters into one object that may seem cleaner to you. Another alternative is to use a dictionary for with all the parameters as the single configuration parameter. Some of Apples classes does this (for example title font configuration in the navigation bar).
I personally would say that code repetition is worse than many methods calling each other and having multiple parameters.
If it allow you to remove many duplicate lines, I don't see any problem to do it this way.
If it's to remove 1 or 2 lines then it might not worth the effort.
In fact you can pass as many arguments as needed. There might be other ways to do what you what to achieve but without the code your 5 arguments seems valid at first glance.
There is no specific number of parameters that is generally "bad practice". A method should have as many parameters as it needs. That said, there are cases where having a large number of parameters may indicate that a better design might be possible. For example, there are cases where you may realize an object should be tracking some value in a member variable instead of having the value passed into its methods every time.
I think it's okay to use 5 params because some objective-c default method are also having 4 params like
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(updateConvMenu:)
notificationName:#"NSConvertersChanged"
object:converterArray];
What we can do to make it more clear is giving a better format to your code
disclaimer: I know zilch about objective c
It is difficult to say without seeing the code in question, and it completely depends on what you are doing. To say that having a method with five parameters is bad practice right off the bat is a bit presumptive, although it is certainly good practice to keep the number of method parameters as small as possible.
The fact that this method sounds like an internal 'helper' method (and not a publicly exposed component of an API) gives you more lee-way then you might otherwise have, but typically you do not want to be in a situation where a method is doing different things based on some arcane combination of parameters.
When I run into methods with uncomfortably long signatures that cannot be restructured without creating redundant code, I typically do one of the following:
wrap the offensive method with several more concise methods. You might create, as an example, a method for each of your 'implementations', with a good name indicating its purpose that accepts only the arguments needed for that purpose. It would then delegate to the internal, smellier method. The smelly method would only ever be used in your 'implementation specific' wrappers instead of being scattered throughout your code. Using the well named wrappers in its stead, developers will understand your intent without having to decipher the meaning of the parameters.
Create a Class that encapsulates the data needed by the method. If what the method does depends on the state of some system or subsystem, then encapsulate that state! I do this often with 'XXContext' type classes. Now your method can inspect and analyze this contextual data and take the appropriate actions. This is good for refactoring as well. If the method in the future needs more information to accomplish its tasks or implement new functionality, you can add this data to the argument object, instead of having to change every bit of code that uses the method. Only code that needs to make use of the changes will have to supply the the appropriate values to the contextual data.
This is one of those subjective questions that's really hard to answer definitively.
I don't mind a number of parameters in an Objective C method as it can make the API that's being called more clear (and the parameters can be nice & type safe, too).
If you can distill those many functions down to a smaller number of functions (or a "base" function which is called from all the other functions), that's probably also makes for cleaner code that's easier to follow and read. Plus if you make an update to that "base" function, the functionality change will be picked up by all the ways you call your action (that's can also be a good or bad thing, of course).
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Say, if in our object design, there is already a Car class, and now there are some cars objects that convertibles.
We can define another class Convertible and subclass Car, but then let's say, we later on create a class that's FourWheelDrive that also subclasses Car, and later on, if we have a FourWheelDrive that is also a Convertible, then how can we handle it?
How is the design above compared with the other design, which is a isConvertible boolean in the Car class, and a isFourWheelDrive boolean also in the Car class, just as flags or properties of the Car class. So we won't define extra classes in this case.
Update: in a real life example, in our project, there was a Credential class that stores a user's info: user_id, encrypted_password, email_address, etc. When we allow logging in through Facebook, Gmail, Yahoo, MySpace (using JanRain), a coworker proposed adding FacebookCredential, GmailCredential, YahooCredential, all these classes that subclass Credential. I was a bit overwhelmed that there are so many classes, and when you see a method, you have to look at whether the subclass overrides it or is it the base class's method. I would have done it just using a code to tell which provider of the credential it is (Facebook, Gmail, etc), and use this provider code to do the appropriate things. (for example, some providers have verified email address, some don't). So I just don't know if my coworker's method is more appropriate or complicated.
You might want to take a different approach by using the http://en.wikipedia.org/wiki/Strategy_pattern
You can define different behaviours for diffrent types of cars, so you don't have lots of subclasses.
You imply that you're using a language which doesn't support multiple inheritance. Does the language support interfaces? You could have a base abstract class Car. (Abstract because one never builds a "car" but instead builds a specific implementation of a car.) Then instances of classes which inherit the abstract base class can implement common interfaces:
IConvertible
IFourWheelDrive
IHybrid
and so on...
The idea is that the abstract base class defines what something is at its simplest. The interfaces define what type of that thing it is, and there can certainly be overlap. Those interfaces would contain the operations and properties which are specific to that type. (An IConvertible would have properties and methods that non-convertibles wouldn't have, same with an IHybrid, etc.) Then the specific implementations could add their own unique flair to the whole thing.
It's a bit of a contrived example, as you know. So it's all conjecture. But for this particular theoretical implementation I'd go with interfaces.
In addition to your concern about four wheel drive cars which are also convertibles, consider the following:
Are all Convertables cars?
Are all vehicles with four wheel drive cars?
To me, these sorts of questions point at these being attributes of car which do not define a type. In a sense, they're no different than color or the number of doors, etc.
It basically comes down to a question whether you need/want to change the functionality of the class based on whether it's a convertible and or four wheel-drive. For example, if you need/want to have a raise_top and lower_top for a convertible, and lock_hubs and unlock_hubs for a four wheel-drive, then you pretty much need to use inheritance to add classes that have those. In such a case, then yes, there's a pretty fair chance that an open-top 4WD vehicle will inherit from both the convertible and 4 wheel-drive classes. As such, if you're doing that in C++, those classes should probably inherit virtually from automobile (or whatever you name your base class), and in something like Java, they'll pretty much need to be interfaces rather than classes.
On the other hand, if you just need to be able to find out whether a particular vehicle is or isn't convertible and/or 4 wheel-drive, then a simple Boolean (or enumerated) field in the class should be perfectly adequate.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Consider the following method:
+(void) myMethod:(int)arg1 **argument2**(int)arg2 **argument3**(int) arg3;
See how the first argument, unlike the 2nd and 3rd, doesn't have a description, giving it an impression of bad symmetry. Also you would expect the extra typing will provide named argument as you pass it in, but you still have to pass them in the correct order.
Can anyone help me make sense of this?
You're missing : after argument2 and argument3
Also, first argument is named myMethod. By Apple's naming recommendation guide, you'd see the method should be named in the manner that identifies semantics of first argument.
EDIT:
check out this document Coding Guidelines - Naming Methods
Hopefully the response to this other question will help you make sense of what you see.
The logic behind this exists though hard to get used to.
regarding your first note, about the naming of the first param,
Apple encourage you to name your methods as follows:
+(void)myMethodWithArg1:(int)arg1 Arg2:(int)arg2 Arg3:(int)arg3;
thus making the name readable like a sentence in english
(my method had Arg1 of type int, Arg2 of type int, etc)
regarding the named params and the inability to change the order, that makes no sence to me either
and the comment above me is correct, you are missing those annoying : after the params
In addition, the syntax of ObjC has strong relation to that of Smalltalk (http://www.smalltalk.org/main/)
I'd encourage you to read on that and the relation between the two languages
hope this helps
The method name is supposed to described the first argument.
Like:
+ (void)updateUserWithId:id andAge:age
So that the whole expression gives sort of a natural sentence.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What is your perspective on downcasting? Is it ALWAYS wrong, or are there cases where it is acceptable, or even preferable or desired?
Is there some good measure/guideline we can give that tells us when downcasting is "evil", and when it's "ok"/"good"?
(I know a similar question exists, but that question spins out from a concrete case. I'd like to have it answered from a general design perspective.)
No, it's definitely not always wrong.
For example, suppose in C# you have an event handler - that gets given a sender parameter, representing the originator of the event. Now you might hook up that event handler to several buttons, but you know they're always buttons. It's reasonable to cast sender to Button within that code.
That's just one example - there are plenty of others. Sometimes it's just a way around a slightly awkward API, other times it comes out of not being able to express the type within the normal type system cleanly. For example, you might have a Dictionary<Type, object> appropriate encapsulated, with generic methods to add and retrieve values - where the value of an entry is of the type of the key. A cast is entirely natural here - you can see that it will always work, and it's giving more type safety to the rest of the system.
It's never an ideal solution and should be avoided wherever possible - unless the alternative would be worse. Sometimes, it cannot be avoided, e.g. pre-Generics Java's Standard API library had lots of classes (most prominently the collections) that required downcasting to be useful. And sometimes, changing the design to avoid the downcast would complicate it significantly, so that the downcast is the better solution.
An example for "legal" downcasting is Java pre 5.0 where you had to downcast container elements to their concrete type when accessing them. It was unavoidable in that context. This also shows the other side of the question though: if you need to downcast a lot in a given situation, it starts to be evil, so it is better to find another solution without downcasting. That resulted in the introduction of generics in Java 5.
John Vlissides analyzes this issue (aka "Type Laundering") a lot in his excellent book Pattern Hatching (practically a sequel to Design Patterns).