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 4 years ago.
Improve this question
I always use one array arguments to a function whenever I need more then 3 parameter.
Example: Consider a function call like this.
processSecondStage($stepTitle, $round, $entryId, $formId, $stepType, $stepAfterApproved, $assigneees, $stageToMove);
I always prefer the below one.
processSecondStage(array(
'stepTitle' => $title,
'round' => $round,
'stepAfterApproved' => $stepAfterApproved,
'entryId' => $_entryId,
'assigneees' => (array)$_POST['flow-asignee'],
'stageToMove' => $currentStep,
'formId' => $targetFormId,
'stepType' => 'approval'
));
Advantage (I might be wrong):
a) Can add more number of parameter
b) Readability
c) Order can be changed easily
d) Default parameter handling is easier
Disadvantage :
a) Code length is increase specially in case when we have less then 3-4 arguments.
Can anyone please help me Know more disadvantage of using the array parameter ?
Whenever I change other developer code (like I am going to do now), then I feel that there are some major disadvantage of using array as parameter because if that was not the case then it should have been a standard practice.
Although I have given example of PHP, but I find this in other language also on which I work.
Thank You.
Arrays are useful as a parameter when things you want to pass are closely related and do not make sense separately. A classical example is a Color that is defined by blue, green, red (and maybe gamma). Combining these parameters into an array (or object in javascript) allows you to swap it out easily.
Always using an array as the single parameter of a function makes you loose out on a parameter list an IDE can give you. For someone reading the code, it is quite a hell to figure out what needs to be passed to a function. It also opens the door to future creep (oh, this function was only making me coffee, but if I add another optional parameter it can also make me tea. Oh, and maybe I can let it make me dinner to. Why not add the functionality to order an attack helicopter too).
In a regular parameter list you can pass things by reference (function pushElement(array &$sortableArray, $element)). This is not expected in a regular array, if it is even possible.
The point about default values is kind of a moot point. Normal parameter lists allow type hinting and default values just fine:
function action(string $action = 'tickle', string $target = 'Polar bear') {
print "I {$action} a {$target}";
}
A single parameter as array probably only really shines when passing some kind of static configuration. You keep the configuration of something separate from the actual code using it, making it easier to modify the configuration. At the same time you leverage the fact that you do not have to send 20 parameters in a very specific order.
In your case the parameter list you give is wildly varied and long, which suggests that your function is doing way too much. Part of it should probably be moved to a constructor and part of it should probably be moved to some kind of Form class.
Parts of the topic are very much opinionated...
The problem you describe is not just parameters as a list vs a sequence of parameters. There are several problems that occur (with both in your example).
Tooling
Ordering of parameters
Semantics
Tooling is probably obvious: If you have only arrays as parameters, no IDE will know what is supposed to be inside. Okay, most IDEs won't know.
Ordering of parameters is usually dictated by the name of the function and/or its semantics. If you drawLine the canonical order of the parameters is ($from, $to). If there is no canonical order, there might be something else wrong with the code... (see below)
Semantics: If you have 3+ parameters (especially if you have way more), it is very likely, that the abstraction is wrong. For example let's assume you have a function createShirt($size="m", int $red, int $blue, int $green, Image $logo, $material="wool"): The order of attributes is arbitrary and the object produced (a shirt) may not need all of those parameters, but you can absolutely use this abstraction. I would much prefer the builder pattern, example:
$shirt = ShirtBuilder::create("m") // verifies m is a size
->setColor(new Color($red,$green,$blue)) // has type-hint color
->setImage($logo) // has type-hint
->setMaterial($material)
->build();
It absolutely is more verbose, but it is apparent you only have to call functions that are needed, you can validate set values at any point (read: function call). The build function could verify that the combination is valid and the Shirt object itself could even be immutable.
However, arrays absolutely do have their place and purpose. But usually it is "providing a list of things of the same type". If your array has only string-keys that are from a very small domain, you probably want an object.
Using objects will trigger questions such as "which parameters should belong to this object?". if there is no semantic reason for a true subset of parameters to appear together, you probably want the command pattern (command objects). and IDEs might provide all the wonders that make using those easy
tl;dr:
Using arrays to hold a list of heterogeneous parameters is probably an anti-pattern (might be warranted in some scenario/language).
Functions/methods with more than 3 parameters suggest too little abstraction (there might be reasons). Use appropriate design patterns.
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
I am not good at naming, I good at feeling.
Suppose we have this hypothetical function:
function computePowerAndPrintResult(int x){
print(x*x);
}
It screams already in the naming of the function ("And") that something wrong here and personally I never write code like this.
Which principle is being violated here? Is it the single-responsibility principle?
Yes. The name is indeed a giveaway. In violation of the single responsibility principle, the function is responsible for two things: computing the square, and printing the result.
Also good naming sense is being violated: at the very least it should be called computeSquareAndPrintResult because Power without specifying the exponent doesn't make much sense. I'd personally call it printSquareOf so you can call it like printSquareOf(x), which reads very naturally.
No it's not. The single responsibility refers to a class. When a class is doing too much then it is violated. When a function is doing to much though you need to break it down.
Now I'm not saying that it's not an indication that it does.
In my mind, you need a class to compute the power, and a class that will manage the printing.
BUT: Assume that I have a need to implement an API that I would call and it would return the PDF of the compute power. I would need an api that would both calculate and print the result.
I would then create the GetSquareValueOutput which would have the single responsibility to orchestrate getting the data from the SquareValueCalculator class and then print with the Printer class.
This last GetSquareValueOutput might as well be called computePowerAndPrintResult and it would not break a thing. I wouldn't choose the name as it hints at a code smell, but in the end it's just a matter of context.
TL;DR: Change the name to printSquare. Then the name is much shorter, is equally accurate at describing what you do, and yet... if you really want worry about the single responsibility principle, you're still breaking it. Which says more about how SRP can easily be overzealously applied, than this being a bad method.
In depth on that name
'computePower' is a bad name for two reasons:
'Power' is a binary operation (X to the Yth power) and you're not really doing that; you've locking Y to '2', and that operation has a common name too: 'square'.
'compute' is usually superfluous. square already implies that calculation is going on. Look at e.g. java's AtomicInteger or BigInteger which have methods named add (really, in the case of BI, should be plus), but the point is, it's not computePlus. Note that it depends on a few factors; for example, in java it is common to start property getters with get, in a class that has an unrelated property or otherwise square is not as clear as one would like (say, its geometrically related, so square could be misunderstood to refer to the shape instead of the mathematical operation), then this is oversimplifying matters as well.
That means that part of the method name ought to be square and not computePower.
Then we have the andPrintResult part. Here Result is superfluous. What else would it be printing, other than the result?
You have 2 options:
This method should be named square and should return that value and not print anything. Make another method to print things.
'and' being a code smell is.. eh. Maybe. Look, you could name this method printSquare which is short, clear, and contains no and, and yet, it's just as much of a violation of the rule as computePowerAndPrintResults.
In many ways printSquare is a straight violation of SRP, but if you change the name to reportSquare, and the code will compute the square and then report it to the configured (injected via dependency injection for example) 'reporter output stream', all of a sudden it's not a violation of SRP, but all we did was redefine some words, the code remained the same.
validationError([elem1,elem2],type,shiftNo);
or
var arr = [elem1,elem2];
validationError(arr,type,shiftNo);
What I mean to ask is approach 1 of calling the function considered bad ( also does it have any performance ramifications). and for that matter is it a bad approach to declare strings, object and functions inside arguments.
Performance is not an issue, not in a language like JS, Ruby or whatnot. So all we can do is think about code readability. And this case is not strongly related to JS, so will be my examples.
move = ["E2", "E4"];
if chessboard.valid(move, player) {
...
}
This clearly states: "if the move (E2 E4) is valid for this chessboard, then...", you don't even need to look at the docs to know that. If we write that without assigning our array a name, the result looks a little cryptic (still easy to guess, but harder for such a tiny example):
if chessboard.valid(["E2", "E4"], player) {
...
}
What is this supposed to mean? What does valid stand for here? Maybe, it's asking whether these cells contain valid player's pieces? This is a sympthom of a design flaw, more precisely bad naming. It makes bold assumptions about how the chessboard code will be used. We can make it obvious that this array represents a move by renaming the chessboard's method:
if chessboard.valid_move(["E2", "E4"], player) {
...
}
This is better, but you may not have an API that allows your code to stay so readable without some additional naming.
So, I suggest a rule of thumb:
If the array will be used more than once, name it.
If the meaning of the array is not obvious from where it goes (function name), name it.
Don't name it, unless points 1 or 2 apply.
It doesn't make any difference really. Either way, you create a Javascript Array, which basically is an Object and get a reference in return (which you pass to your method). If you don't need to access that array (or other data) later in your code, the second approach is completely fine.
Are the contents of arr ever going to get used again? If so, then option 2 is definitely the way to go. If not... something as simple as this is probably just personal opinion.
Personally, I'd have to say that option 2 is better practice, even though sometimes I'm guilty of using option 1. Option 2 is easier to read, it's easier to follow and it's less likely someone will have to re-read it because they became temporarily confused or lost in flow of thought whilst reading through your code (especially newer programmers). For those reasons it's easier to maintain, you, and potentially future developers working with your code, will likely save time working with it.
The only negatives I can see would be generating an absolutely miniscule amount of overhead, and now you have 2 lines of code instead of 1. But I think that's irrelevant, the tiny potential benefits of option 2 outweigh the tiny negatives of option 1.
It is subjective, but in my opinion it is better to use the second approach.
As #jAndy said there is no difference in the code execution neither the performance of your code, but it is easier to debug and easier to read and understand the second approach.
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 9 years ago.
Improve this question
I'm interested in how you guys lay out your Javascript objects/classes when they contain lots of functions, all of which need to be on the same 'level' (i.e. they need to remain as first level functions of the object).
So with a structure like this...
Namespace.class = {
abc: 1,
def: 2,
ghi: 3,
funcA: function(){
// Some logic
},
funcB: function(){
// Some logic
},
// Lots more functions
funcN: function(){
// Some logic
}
}
This can all get pretty unwieldy. How do you lay out these types of objects to make them readable, easy to maintain and quick for new developers to pick up?
My approach has been to organise everything in alphabetical order, so you know roughly where to go if you know a function's name.
But does it make more sense to group functions that are closely related in what they do and those that refer to eachother?
There are many approaches here and it depends on how exactly you interact with your code.
Some things to keep in mind:
1) If the code is unwieldy, a refactoring is probably overdue.
Consider breaking your class into smaller classes each dealing with different aspects of what the big class does. Split functionality in multiple namespaces if you use static functions rather than classes.
Consider splitting functionality over multiple files (one-class-per-file for example) and having a build process that combines and minifies your output.
2) Tools can help.
If you deal with large codebases it's probably a good idea to find an editor (or learn to use its functions better) that can help you deal with it. Your IDE will probably have some functionality to help you navigate the file structure better, like a file structure overview, or code regions, or objects view
3) Organize functions by what makes sense.
An alphabetic solution could make sense in some situations, but grouping by functionality is probably better. Putting exported methods all in one place is probably a good idea as well:
Namespace = function() {
var f1 = function() { };
var f2 = function() { }; // this is internal
// Exported methods
return {
f1 : f1
}
}();
4) Document your code.
While reading the code is invaluable in giving someone an in-depth understanding, code ducmentation is essential in having a first-glance understanding. It can also be useful to you during development because you don't have to remember all the quirks of your code.
5) Enforce a coding style that can help you.
Your coding style can help you find things in the code easier. If you always use the same spacing, put braces the same way, etc, finding a function definition can be as easy as Ctrl-f: myFunc:.
One approach is to modularize the class, and split it across multiple files. Typically this approach is used to provide plugins to a core class. jQuery is a great example of where the class has been extended using plugins.
When you're not interested in splitting the same class across multiple files, I find alphabetizing the function order helps.
In the end the order of the functions shouldn't matter so long as you have a good enough IDE that it lets you jump to the definition for that function.
God objects are an anti-pattern and a good indicator that you have some serious design flaws.
If you follow the single responsability principle and have a smart IDE that supports intellisense and other similar features, the investment for trying to keep everything ordered is not worth and not necessary since that would be the IDE's job to show all function definitions ordered in a panel for quick-access and to have a global overview.
If you really want to order your functions you could have an automated process that keeps your object literals structured.
However that doesn't mean you shouldn't have any coding standards. I also still organize my code in a way that makes sense e.g. private/public/priviledged members together.
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 9 years ago.
Improve this question
As I am writing some code, I am wondering how secure my methods should be. Should I trust the user of my class ? Or check everything ? This implies parameters type checking which may not be a good practice as Javascript is supposed to be duck typed.
Basically this leads to the question of trust. Is there a best practice ? Is there an implicit "contract" ?
Example :
CarsCollection.prototype.get = function ( index ) {
return this.collection[index];
};
Or
CarsCollection.prototype.get = function ( index ) {
var self = this;
if ( ! index ) {
throw new ReferenceError();
}
if ( isNaN ( index ) ) {
throw new TypeError();
}
return self.collection[index];
};
You'll find out how robust your methods are by unit testing them. If you write good tests, you'll quickly find that your methods need to be able to handle all kinds of wack input.
It is up to you how far you want to go, but to be clear: don't just assume that the inputs will be valid.
Personally, I validate the hell out of anything that is coming from another class/module/whatever, even if its not third party. You need to make sure that the entry points to each module are robust. I relax a little more within a given class/module, but still make sure to validate enough to prevent errors.
In your sample code, it looks like other pieces of code outside of CarsCollection will be calling the get method. So, you'll want to validate index for sure.
In general things like framework code and reusable libraries are the prime candidate for extensive argument checking because you (and your current and future colleagues) going to use this code a lot.
You don't have to add argument checks everywhere, just use them when it's sensible.
If you want to specify certain behaviour like: should array_delete_value modify the input argument or return a copy with the value removed? Specify it in the comments and add a test that tests for exactly this behaviour.
If you're worried about performance you can write assert-like statements and remove them in your minification step. This is analogous to compiling with asserts off.
Asserts could look like:
argument("index", index).of_type("number").required();
If you downvoted, could you please leave a comment. Did I miss something? Do you have a competing methodology?
I like to make my code as dummy-proof as possible. This reduces the number of WTF's elicited by developers using my API/function/code. Argument-checking is always a good practice, especially in a dynamically-typed language like JavaScript. So there is nothing wrong with what you are doing. Type checking is permissible in JavaScript also. I find it easier to keep track of a function that explicitly states the types of its arguments. This lessens the cognitive load on the user of your API (i.e., not having to deal with foo(5) and foo("5")) and also lessens your own cognitive-load when you are writing the function since you won't have to deal with the idiosyncrasies of JavaScript's types and can be sure that an argument is the type that you expect.
While this doesn't exactly answer your question, it's important to note that the looseness of javascript makes many of your issues a non-issue (unless you want them to be).
If index is falsey, and you look at collection[index], you'll simply get undefined. I'm honestly not sure if that's a feature of arrays/objects or if the falsey value got coerced to a 0, but either way, it's not officially an error.
If index is not a number, the bracket notation will fall back from looking for an array member to an object property. In the worst case, it will return undefined, but in the best case, you can use the dynamic capabilities of objects to your advantage.
Realize that your current check will fail on CarsCollection.get(0), since 0 is falsey.
Also, isNaN handles if its parameter is null or undefined.
So neither of the things you check for are an error. If it was a fatal error, JavaScript would throw an error itself.
Now, to the question itself, my opinion is that javascript is so loose and uncontained, that most checking is unnecessary. If the using function passes bad parameters, the other programmer should figure out why. It's not like you can hide your code from them. The thing I value most is good documentation (check out jsdoc, then use it). If you define your interface well, the programmer can use it. That's just IMO, though.
I've started to wrap my functions inside of Objects, e.g.:
var Search = {
carSearch: function(color) {
},
peopleSearch: function(name) {
},
...
}
This helps a lot with readability, but I continue to have issues with reusabilty. To be more specific, the difficulty is in two areas:
Receiving parameters. A lot of times I will have a search screen with multiple input fields and a button that calls the javascript search function. I have to either put a bunch of code in the onclick of the button to retrieve and then martial the values from the input fields into the function call, or I have to hardcode the HTML input field names/IDs so that I can subsequently retrieve them with Javascript. The solution I've settled on for this is to pass the field names/IDs into the function, which it then uses to retrieve the values from the input fields. This is simple but really seems improper.
Returning values. The effect of most Javascript calls tends to be one in which some visual on the screen changes directly, or as a result of another action performed in the call. Reusability is toast when I put these screen-altering effects at the end of a function. For example, after a search is completed I need to display the results on the screen.
How do others handle these issues? Putting my thinking cap on leads me to believe that I need to have an page-specific layer of Javascript between each use in my application and the generic methods I create which are to be used application-wide. Using the previous example, I would have a search button whose onclick calls a myPageSpecificSearchFunction, in which the search field IDs/names are hardcoded, which marshals the parameters and calls the generic search function. The generic function would return data/objects/variables only, and would not directly read from or make any changes to the DOM. The page-specific search function would then receive this data back and alter the DOM appropriately.
Am I on the right path or is there a better pattern to handle the reuse of Javascript objects/methods?
Basic Pattern
In terms of your basic pattern, can I suggest modifying your structure to use the module pattern and named functions:
var Search = (function(){
var pubs = {};
pubs.carSearch = carSearch;
function carSearch(color) {
}
pubs.peopleSearch = peopleSearch;
function peopleSearch(name) {
}
return pubs;
})();
Yes, that looks more complicated, but that's partially because there's no helper function involved. Note that now, every function has a name (your previous functions were anonymous; the properties they were bound to had names, but the functions didn't, which has implications in terms of the display of the call stack in debuggers and such). Using the module pattern also gives you the ability to have completely private functions that only the functions within your Search object can access. (Just declare the functions within the big anonymous function and don't add them to pubs.) More on my rationale for that (with advantages and disadvantages, and why you can't combine the function declaration and property assignment) here.
Retrieving Parameters
One of the functions I really, really like from Prototype is the Form#serialize function, which walks through the form elements and builds a plain object with a property for each field based on the field's name. (Prototype's current – 1.6.1 – implementation has an issue where it doesn't preserve the order of the fields, but it's surprising how rarely that's a problem.) It sounds like you would be well-served by such a thing and they're not hard to build; then your business logic is dealing with objects with properties named according to what they're related to, and has no knowledge of the actual form itself.
Returning Values / Mixing UI and Logic
I tend to think of applications as objects and the connections and interactions between them. So I tend to create:
Objects representing the business model and such, irrespective of interface (although, of course, the business model is almost certainly partially driven by the interface). Those objects are defined in one place, but used both client- and server-side (yes, I use JavaScript server-side), and designed with serialization (via JSON, in my case) in mind so I can send them back and forth easily.
Objects server-side that know how to use those to update the underlying store (since I tend to work on projects with an underlying store), and
Objects client-side that know how to use that information to render to the UI.
(I know, hardly original!) I try to keep the store and rendering objects generic so they mostly work by looking at the public properties of the business objects (which is pretty much all of the properties; I don't use the patterns like Crockford's that let you really hide data, I find them too expensive). Pragmatism means sometimes the store or rendering objects just have to know what they're dealing with, specifically, but I do try to keep things generic where I can.
I started out using the module pattern, but then started doing everything in jQuery plugins. The plugins allow to pass page specific options.
Using jQuery would also let you rethink the way you identify your search terms and find their values. You might consider adding a class to every input, and use that class to avoid specifically naming each input.
Javascript is ridiculously flexible which means that your design is especially important as you can do things in many different ways. This is what probably makes Javascript feel less like lending itself to re-usability.
There are a few different notations for declaring your objects (functions/classes) and then namespacing them. It's important to understand these differences. As mentioned in a comment on here 'namespacing is a breeze' - and is a good place to start.
I wouldn't be able to go far enough in this reply and would only be paraphrasing, so I recommend buying these books:
Pro JavaScript Design Patterns
Pro Javascript techniques