JAVA 8 Extract predicates as fields or methods? - java-8

What is the cleaner way of extracting predicates which will have multiple uses. Methods or Class fields?
The two examples:
1.Class Field
void someMethod() {
IntStream.range(1, 100)
.filter(isOverFifty)
.forEach(System.out::println);
}
private IntPredicate isOverFifty = number -> number > 50;
2.Method
void someMethod() {
IntStream.range(1, 100)
.filter(isOverFifty())
.forEach(System.out::println);
}
private IntPredicate isOverFifty() {
return number -> number > 50;
}
For me, the field way looks a little bit nicer, but is this the right way? I have my doubts.

Generally you cache things that are expensive to create and these stateless lambdas are not. A stateless lambda will have a single instance created for the entire pipeline (under the current implementation). The first invocation is the most expensive one - the underlying Predicate implementation class will be created and linked; but this happens only once for both stateless and stateful lambdas.
A stateful lambda will use a different instance for each element and it might make sense to cache those, but your example is stateless, so I would not.
If you still want that (for reading purposes I assume), I would do it in a class Predicates let's assume. It would be re-usable across different classes as well, something like this:
public final class Predicates {
private Predicates(){
}
public static IntPredicate isOverFifty() {
return number -> number > 50;
}
}
You should also notice that the usage of Predicates.isOverFifty inside a Stream and x -> x > 50 while semantically the same, will have different memory usages.
In the first case, only a single instance (and class) will be created and served to all clients; while the second (x -> x > 50) will create not only a different instance, but also a different class for each of it's clients (think the same expression used in different places inside your application). This happens because the linkage happens per CallSite - and in the second case the CallSite is always different.
But that is something you should not rely on (and probably even consider) - these Objects and classes are fast to build and fast to remove by the GC - whatever fits your needs - use that.

To answer, it's better If you expand those lambda expressions for old fashioned Java. You can see now, these are two ways we used in our codes. So, the answer is, it all depends how you write a particular code segment.
private IntPredicate isOverFifty = new IntPredicate<Integer>(){
public void test(number){
return number > 50;
}
};
private IntPredicate isOverFifty() {
return new IntPredicate<Integer>(){
public void test(number){
return number > 50;
}
};
}

1) For field case you will have always allocated predicate for each new your object. Not a big deal if you have a few instances, likes, service. But if this is a value object which can be N, this is not good solution. Also keep in mind that someMethod() may not be called at all. One of possible solution is to make predicate as static field.
2) For method case you will create the predicate once every time for someMethod() call. After GC will discard it.

Related

Removing a std::function<()> from a vector c++

I'm building a publish-subscribe class (called SystermInterface), which is responsible to receive updates from its instances, and publish them to subscribers.
Adding a subscriber callback function is trivial and has no issues, but removing it yields an error, because std::function<()> is not comparable in C++.
std::vector<std::function<void()> subs;
void subscribe(std::function<void()> f)
{
subs.push_back(f);
}
void unsubscribe(std::function<void()> f)
{
std::remove(subs.begin(), subs.end(), f); // Error
}
I've came down to five solutions to this error:
Registering the function using a weak_ptr, where the subscriber must keep the returned shared_ptr alive.
Solution example at this link.
Instead of registering at a vector, map the callback function by a custom key, unique per callback function.
Solution example at this link
Using vector of function pointers. Example
Make the callback function comparable by utilizing the address.
Use an interface class (parent class) to call a virtual function.
In my design, all intended classes inherits a parent class called
ServiceCore, So instead of registering a callback function, just
register ServiceCore reference in the vector.
Given that the SystemInterface class has a field attribute per instance (ID) (Which is managed by ServiceCore, and supplied to SystemInterface by constructing a ServiceCore child instance).
To my perspective, the first solution is neat and would work, but it requires handling at subscribers, which is something I don't really prefer.
The second solution would make my implementation more complex, where my implementation looks as:
using namespace std;
enum INFO_SUB_IMPORTANCE : uint8_t
{
INFO_SUB_PRIMARY, // Only gets the important updates.
INFO_SUB_COMPLEMENTARY, // Gets more.
INFO_SUB_ALL // Gets all updates
};
using CBF = function<void(string,string)>;
using INFO_SUBTREE = map<INFO_SUB_IMPORTANCE, vector<CBF>>;
using REQINF_SUBS = map<string, INFO_SUBTREE>; // It's keyed by an iterator, explaining it goes out of the question scope.
using INFSRC_SUBS = map<string, INFO_SUBTREE>;
using WILD_SUBS = INFO_SUBTREE;
REQINF_SUBS infoSubrs;
INFSRC_SUBS sourceSubrs;
WILD_SUBS wildSubrs;
void subscribeInfo(string info, INFO_SUB_IMPORTANCE imp, CBF f) {
infoSubrs[info][imp].push_back(f);
}
void subscribeSource(string source, INFO_SUB_IMPORTANCE imp, CBF f) {
sourceSubrs[source][imp].push_back(f);
}
void subscribeWild(INFO_SUB_IMPORTANCE imp, CBF f) {
wildSubrs[imp].push_back(f);
}
The second solution would require INFO_SUBTREE to be an extended map, but can be keyed by an ID:
using KEY_T = uint32_t; // or string...
using INFO_SUBTREE = map<INFO_SUB_IMPORTANCE, map<KEY_T,CBF>>;
For the third solution, I'm not aware of the limitations given by using function pointers, and the consequences of the fourth solution.
The Fifth solution would eliminate the purpose of dealing with CBFs, but it'll be more complex at subscriber-side, where a subscriber is required to override the virtual function and so receives all updates at one place, in which further requires filteration of the message id and so direct the payload to the intended routines using multiple if/else blocks, which will increase by increasing subscriptions.
What I'm looking for is an advice for the best available option.
Regarding your proposed solutions:
That would work. It can be made easy for the caller: have subscribe() create the shared_ptr and corresponding weak_ptr objects, and let it return the shared_ptr.
Then the caller must not lose the key. In a way this is similar to the above.
This of course is less generic, and then you can no longer have (the equivalent of) captures.
You can't: there is no way to get the address of the function stored inside a std::function. You can do &f inside subscribe() but that will only give you the address of the local variable f, which will go out of scope as soon as you return.
That works, and is in a way similar to 1 and 2, although now the "key" is provided by the caller.
Options 1, 2 and 5 are similar in that there is some other data stored in subs that refers to the actual std::function: either a std::shared_ptr, a key or a pointer to a base class. I'll present option 6 here, which is kind of similar in spirit but avoids storing any extra data:
Store a std::function<void()> directly, and return the index in the vector where it was stored. When removing an item, don't std::remove() it, but just set it to std::nullptr. Next time subscribe() is called, it checks if there is an empty element in the vector and reuses it:
std::vector<std::function<void()> subs;
std::size_t subscribe(std::function<void()> f) {
if (auto it = std::find(subs.begin(), subs.end(), std::nullptr); it != subs.end()) {
*it = f;
return std::distance(subs.begin(), it);
} else {
subs.push_back(f);
return subs.size() - 1;
}
}
void unsubscribe(std::size_t index) {
subs[index] = std::nullptr;
}
The code that actually calls the functions stored in subs must now of course first check against std::nullptrs. The above works because std::nullptr is treated as the "empty" function, and there is an operator==() overload that can check a std::function against std::nullptr, thus making std::find() work.
One drawback of option 6 as shown above is that a std::size_t is a rather generic type. To make it safer, you might wrap it in a class SubscriptionHandle or something like that.
As for the best solution: option 1 is quite heavy-weight. Options 2 and 5 are very reasonable, but 6 is, I think, the most efficient.

Creating composite key class for Secondary Sort

I am trying to create a composite key class of a String uniqueCarrier and int month for Secondary Sort. Can anyone tell me, what are the steps for the same.
Looks like you have an equality problem since you're not using uniqueCarrier in your compareTo method. You need to use uniqueCarrier in your compareTo and equals methods (also define an equals method). From the java lang reference
The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C. Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false.
You can also implement a RawComparator so that you can compare them without deserializing for some faster performance.
However, I recommend (as I always do) to not write things like Secondary Sort yourself. These have been implemented (as well as dozens of other optimizations) in projects like Pig and Hive. E.g. if you were using Hive, all you need to write is:
SELECT ...
FROM my_table
ORDER BY month, carrier;
The above is a lot simpler to write than trying to figure out how to write Secondary Sorts (and eventually when you need to use it again, how to do it in a generic fashion). MapReduce should be considered a low level programming paradigm and should only be used (IMHO) when you need high performance optimizations that you don't get from higher level projects like Pig or Hive.
EDIT: Forgot to mention about Grouping comparators, see Matt's answer
Your compareTo() implementation is incorrect. You need to sort first on uniqueCarrier, then on month to break equality:
#Override
public int compareTo(CompositeKey other) {
if (this.getUniqueCarrier().equals(other.getUniqueCarrier())) {
return this.getMonth().compareTo(other.getMonth());
} else {
return this.getUniqueCarrier().compareTo(other.getUniqueCarrier());
}
}
One suggestion though: I typically choose to implement my attributes directly as Writable types if possible (for example, IntWriteable month and Text uniqueCarrier). This allows me to call write and readFields directly on them, and also use their compareTo. Less code to write is always good...
Speaking of less code, you don't have to call the parent constructor for your composite key.
Now for what is left to be done:
My guess is you are still missing a hashCode() method, which should only return the hash of the attribute you want to group on, in this case uniqueCarrier. This method is called by the default Hadoop partitionner to distribute work across reducers.
I would also write custom GroupingComparator and SortingComparator to make sure grouping happens only on uniqueCarrier, and that sorting behaves according to CompositeKey compareTo():
public class CompositeGroupingComparator extends WritableComparator {
public CompositeGroupingComparator() {
super(CompositeKey.class, true);
}
#Override
public int compare(WritableComparable a, WritableComparable b) {
CompositeKey first = (CompositeKey) a;
CompositeKey second = (CompositeKey) b;
return first.getUniqueCarrier().compareTo(second.getUniqueCarrier());
}
}
public class CompositeSortingComparator extends WritableComparator {
public CompositeSortingComparator()
{
super (CompositeKey.class, true);
}
#Override
public int compare (WritableComparable a, WritableComparable b){
CompositeKey first = (CompositeKey) a;
CompositeKey second = (CompositeKey) b;
return first.compareTo(second);
}
}
Then, tell your Driver to use those two:
job.setSortComparatorClass(CompositeSortingComparator.class);
job.setGroupingComparatorClass(CompositeGroupingComparator.class);
Edit: Also see Pradeep's suggestion of implementing RawComparator to prevent having to unmarshall to an Object each time, if you want to optimize further.

Jsprit VRP with multiple Time Windows

I try to use jsprit to solve a VRP with multiple TimeWindows. Therefore I created a new Constraint-Class which contains a Map that relates a "TimeWindowsNotAvailable"-class to a Service.
The "TimeWindowsNotAvailable"-class contains a List of TimeWindows where the Service can't be done (e.g. customer is not at home etc.).
The main problem is, that the newAct.getArrTime() is always 0.0, although you can see in the solution of the VRP that the arrTime is not 0.0.
Does anybody have an idea how I can fix this issue or are multiple TimeWindows much harder to implement?
public class TimeConstraint implements HardActivityStateLevelConstraint {
private Map<Service, TimeWindowsNotAvailable> notAvailableMap;
private RouteAndActivityStateGetter states;
private VehicleRoutingTransportCosts routingCosts;
public TimeConstraint() {
super();
}
public boolean checkDepTime(Service service, Double depTime){
TimeWindowsNotAvailable timeWindowsNotAvailable = notAvailableMap.get(service);
if(timeWindowsNotAvailable == null) return true;
System.out.println(depTime);
return timeWindowsNotAvailable.isAvailable(depTime);
}
public void setNotAvailableMap(Map<Service, TimeWindowsNotAvailable> notAvailableMap){
this.notAvailableMap = notAvailableMap;
}
#Override
public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
Service currentService = (Service)iFacts.getJob();
if(checkDepTime(currentService, **newAct.getArrTime()**)) return ConstraintsStatus.FULFILLED;
return ConstraintsStatus.NOT_FULFILLED;
}
}
You cannot yet model multiple time windows out-of-the box but it is going to be implemented. For the time being, you can implement your own. Assume you have for example the following two time windows for a service: (e1,l1), (e2,l2) where e means earliest operation start and l latest. If l1 < e2, it is comparably "easy" to implement. Just look at how I implemented single hard time windows. Look at which is the TimeWindowConstraint and which is the practical time window state updater. You probably only need minor modifications of these classes, so just copy them and add multiple time windows, and add these two new classes to your State- and ConstraintManager (do not forget to deactivate the default time window constraints/stateUpdater).
The newAct does not have any arrTime since it is not yet inserted into the route and the best insertion position is still to be determined (by checking constraints and calculating marginal insertion costs). But you can easily calculate it as follows:
double newActArrTime = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime,iFacts.getNewDriver(),iFacts.getNewVehicle);

Avoiding duplicate code when performing operation on different object properties

I have recently run into a problem which has had me thinking in circles. Assume that I have an object of type O with properties O.A and O.B. Also assume that I have a collection of instances of type O, where O.A and O.B are defined for each instance.
Now assume that I need to perform some operation (like sorting) on a collection of O instances using either O.A or O.B, but not both at any given time. My original solution is as follows.
Example -- just for demonstration, not production code:
public class O {
int A;
int B;
}
public static class Utils {
public static void SortByA (O[] collection) {
// Sort the objects in the collection using O.A as the key. Note: this is custom sorting logic, so it is not simply a one-line call to a built-in sort method.
}
public static void SortByB (O[] collection) {
// Sort the objects in the collection using O.B as the key. Same logic as above.
}
}
What I would love to do is this...
public static void SortAgnostic (O[] collection, FieldRepresentation x /* some non-bool, non-int variable representing whether to chose O.A or O.B as the sorting key */) {
// Sort by whatever "x" represents...
}
... but creating a new, highly-specific type that I will have to maintain just to avoid duplicating a few lines of code seems unnecessary to me. Perhaps I am incorrect on that (and I am sure someone will correct me if that statement is wrong :D), but that is my current thought nonetheless.
Question: What is the best way to implement this method? The logic that I have to implement is difficult to break down into smaller methods, as it is already fairly optimized. At the root of the issue is the fact that I need to perform the same operation using different properties of an object. I would like to stay away from using codes/flags/etc. in the method signature if possible so that the solution can be as robust as possible.
Note: When answering this question, please approach it from an algorithmic point of view. I am aware that some language-specific features may be suitable alternatives, but I have encountered this problem before and would like to understand it from a relatively language-agnostic viewpoint. Also, please do not constrain responses to sorting solutions only, as I have only chosen it as an example. The real question is how to avoid code duplication when performing an identical operation on two different properties of an object.
"The real question is how to avoid code duplication when performing an identical operation on two different properties of an object."
This is a very good question as this situation arises all the time. I think, one of the best ways to deal with this situation is to use the following pattern.
public class O {
int A;
int B;
}
public doOperationX1() {
doOperationX(something to indicate which property to use);
}
public doOperationX2() {
doOperationX(something to indicate which property to use);
}
private doOperationX(input ) {
// actual work is done here
}
In this pattern, the actual implementation is performed in a private method, which is called by public methods, with some extra information. For example, in this case, it can be
doOperationX(A), or doOperationX(B), or something like that.
My Reasoning: In my opinion this pattern is optimal as it achieves two main requirements:
It keeps the public interface descriptive and clear, as it keeps operations separate, and avoids flags etc that you also mentioned in your post. This is good for the client.
From the implementation perspective, it prevents duplication, as it is in one place. This is good for the development.
A simple way to approach this I think is to internalize the behavior of choosing the sort field to the class O itself. This way the solution can be language-agnostic.
The implementation in Java could be using an Abstract class for O, where the purpose of the abstract method getSortField() would be to return the field to sort by. All that the invocation logic would need to do is to implement the abstract method to return the desired field.
O o = new O() {
public int getSortField() {
return A;
}
};
The problem might be reduced to obtaining the value of the specified field from the given object so it can be use for sorting purposes, or,
TField getValue(TEntity entity, string fieldName)
{
// Return value of field "A" from entity,
// implementation depends on language of choice, possibly with
// some sort of reflection support
}
This method can be used to substitute comparisons within the sorting algorithm,
if (getValue(o[i], "A")) > getValue(o[j], "A"))
{
swap(i, j);
}
The field name can then be parametrized, as,
public static void SortAgnostic (O[] collection, string fieldName)
{
if (getValue(collection[i], fieldName)) > getValue(collection[j], fieldName))
{
swap(i, j);
}
...
}
which you can use like SortAgnostic(collection, "A").
Some languages allow you to express the field in a more elegant way,
public static void SortAgnostic (O[] collection, Expression fieldExpression)
{
if (getValue(collection[i], fieldExpression)) >
getValue(collection[j], fieldExpression))
{
swap(i, j);
}
...
}
which you can use like SortAgnostic(collection, entity => entity.A).
And yet another option can be passing a pointer to a function which will return the value of the field needed,
public static void SortAgnostic (O[] collection, Function getValue)
{
if (getValue(collection[i])) > getValue(collection[j]))
{
swap(i, j);
}
...
}
which given a function,
TField getValueOfA(TEntity entity)
{
return entity.A;
}
and passing it like SortAgnostic(collection, getValueOfA).
"... but creating a new, highly-specific type that I will have to maintain just to avoid duplicating a few lines of code seems unnecessary to me"
That is why you should use available tools like frameworks or other typo of code libraries that provide you requested solution.
When some mechanism is common that mean it can be moved to higher level of abstraction. When you can not find proper solution try to create own one. Think about the result of operation as not part of class functionality. The sorting is only a feature, that why it should not be part of your class from the beginning. Try to keep class as simple as possible.
Do not worry premature about the sense of having something small just because it is small. Focus on the final usage of it. If you use very often one type of sorting just create a definition of it to reuse it. You do not have to necessary create a utill class and then call it. Sometimes the base functionality enclosed in utill class is fair enough.
I assume that you use Java:
In your case the wheal was already implemented in person of Collection#sort(List, Comparator).
To full fill it you could create a Enum type that implement Comparator interface with predefined sorting types.

What's the best way to refactor a method that has too many (6+) parameters?

Occasionally I come across methods with an uncomfortable number of parameters. More often than not, they seem to be constructors. It seems like there ought to be a better way, but I can't see what it is.
return new Shniz(foo, bar, baz, quux, fred, wilma, barney, dino, donkey)
I've thought of using structs to represent the list of parameters, but that just seems to shift the problem from one place to another, and create another type in the process.
ShnizArgs args = new ShnizArgs(foo, bar, baz, quux, fred, wilma, barney, dino, donkey)
return new Shniz(args);
So that doesn't seem like an improvement. So what is the best approach?
I'm going to assume you mean C#. Some of these things apply to other languages, too.
You have several options:
switch from constructor to property setters. This can make code more readable, because it's obvious to the reader which value corresponds to which parameters. Object Initializer syntax makes this look nice. It's also simple to implement, since you can just use auto-generated properties and skip writing the constructors.
class C
{
public string S { get; set; }
public int I { get; set; }
}
new C { S = "hi", I = 3 };
However, you lose immutability, and you lose the ability to ensure that the required values are set before using the object at compile time.
Builder Pattern.
Think about the relationship between string and StringBuilder. You can get this for your own classes. I like to implement it as a nested class, so class C has related class C.Builder. I also like a fluent interface on the builder. Done right, you can get syntax like this:
C c = new C.Builder()
.SetX(4) // SetX is the fluent equivalent to a property setter
.SetY("hello")
.ToC(); // ToC is the builder pattern analog to ToString()
// Modify without breaking immutability
c = c.ToBuilder().SetX(2).ToC();
// Still useful to have a traditional ctor:
c = new C(1, "...");
// And object initializer syntax is still available:
c = new C.Builder { X = 4, Y = "boing" }.ToC();
I have a PowerShell script that lets me generate the builder code to do all this, where the input looks like:
class C {
field I X
field string Y
}
So I can generate at compile time. partial classes let me extend both the main class and the builder without modifying the generated code.
"Introduce Parameter Object" refactoring. See the Refactoring Catalog. The idea is that you take some of the parameters you're passing and put them in to a new type, and then pass an instance of that type instead. If you do this without thinking, you will end up back where you started:
new C(a, b, c, d);
becomes
new C(new D(a, b, c, d));
However, this approach has the greatest potential to make a positive impact on your code. So, continue by following these steps:
Look for subsets of parameters that make sense together. Just mindlessly grouping all parameters of a function together doesn't get you much; the goal is to have groupings that make sense. You'll know you got it right when the name of the new type is obvious.
Look for other places where these values are used together, and use the new type there, too. Chances are, when you've found a good new type for a set of values that you already use all over the place, that new type will make sense in all those places, too.
Look for functionality that is in the existing code, but belongs on the new type.
For example, maybe you see some code that looks like:
bool SpeedIsAcceptable(int minSpeed, int maxSpeed, int currentSpeed)
{
return currentSpeed >= minSpeed & currentSpeed < maxSpeed;
}
You could take the minSpeed and maxSpeed parameters and put them in a new type:
class SpeedRange
{
public int Min;
public int Max;
}
bool SpeedIsAcceptable(SpeedRange sr, int currentSpeed)
{
return currentSpeed >= sr.Min & currentSpeed < sr.Max;
}
This is better, but to really take advantage of the new type, move the comparisons into the new type:
class SpeedRange
{
public int Min;
public int Max;
bool Contains(int speed)
{
return speed >= min & speed < Max;
}
}
bool SpeedIsAcceptable(SpeedRange sr, int currentSpeed)
{
return sr.Contains(currentSpeed);
}
And now we're getting somewhere: the implementation of SpeedIsAcceptable() now says what you mean, and you have a useful, reusable class. (The next obvious step is to make SpeedRange in to Range<Speed>.)
As you can see, Introduce Parameter Object was a good start, but its real value was that it helped us discover a useful type that has been missing from our model.
The best way would be to find ways to group the arguments together. This assumes, and really only works if, you would end up with multiple "groupings" of arguments.
For instance, if you are passing the specification for a rectangle, you can pass x, y, width, and height or you could just pass a rectangle object that contains x, y, width, and height.
Look for things like this when refactoring to clean it up somewhat. If the arguments really can't be combined, start looking at whether you have a violation of the Single Responsibility Principle.
If it's a constructor, particularly if there are multiple overloaded variants, you should look at the Builder pattern:
Foo foo = new Foo()
.configBar(anything)
.configBaz(something, somethingElse)
// and so on
If it's a normal method, you should think about the relationships between the values being passed, and perhaps create a Transfer Object.
The classic answer to this is to use a class to encapsulate some, or all, of the parameters. In theory that sounds great, but I'm the kind of guy who creates classes for concepts that have meaning in the domain, so it's not always easy to apply this advice.
E.g. instead of:
driver.connect(host, user, pass)
You could use
config = new Configuration()
config.setHost(host)
config.setUser(user)
config.setPass(pass)
driver.connect(config)
YMMV
When I see long parameter lists, my first question is whether this function or object is doing too much. Consider:
EverythingInTheWorld earth=new EverythingInTheWorld(firstCustomerId,
lastCustomerId,
orderNumber, productCode, lastFileUpdateDate,
employeeOfTheMonthWinnerForLastMarch,
yearMyHometownWasIncorporated, greatGrandmothersBloodType,
planetName, planetSize, percentWater, ... etc ...);
Of course this example is deliberately ridiculous, but I've seen plenty of real programs with examples only slightly less ridiculous, where one class is used to hold many barely related or unrelated things, apparently just because the same calling program needs both or because the programmer happened to think of both at the same time. Sometimes the easy solution is to just break the class into multiple pieces each of which does its own thing.
Just slightly more complicated is when a class really does need to deal with multiple logical things, like both a customer order and general information about the customer. In these cases, crate a class for customer and a class for order, and let them talk to each other as necessary. So instead of:
Order order=new Order(customerName, customerAddress, customerCity,
customerState, customerZip,
orderNumber, orderType, orderDate, deliveryDate);
We could have:
Customer customer=new Customer(customerName, customerAddress,
customerCity, customerState, customerZip);
Order order=new Order(customer, orderNumber, orderType, orderDate, deliveryDate);
While of course I prefer functions that take just 1 or 2 or 3 parameters, sometimes we have to accept that, realistically, this function takes a bunch, and that the number of itself does not really create complexity. For example:
Employee employee=new Employee(employeeId, firstName, lastName,
socialSecurityNumber,
address, city, state, zip);
Yeah, it's a bunch of fields, but probably all we're going to do with them is save them to a database record or throw them on a screen or some such. There's not really a lot of processing here.
When my parameter lists do get long, I much prefer if I can give the fields different data types. Like when I see a function like:
void updateCustomer(String type, String status,
int lastOrderNumber, int pastDue, int deliveryCode, int birthYear,
int addressCode,
boolean newCustomer, boolean taxExempt, boolean creditWatch,
boolean foo, boolean bar);
And then I see it called with:
updateCustomer("A", "M", 42, 3, 1492, 1969, -7, true, false, false, true, false);
I get concerned. Looking at the call, it's not at all clear what all these cryptic numbers, codes, and flags mean. This is just asking for errors. A programmer might easily get confused about the order of the parameters and accidentally switch two, and if they're the same data type, the compiler would just accept it. I'd much rather have a signature where all these things are enums, so a call passes in things like Type.ACTIVE instead of "A" and CreditWatch.NO instead of "false", etc.
This is quoted from Fowler and Beck book: "Refactoring"
Long Parameter List
In our early programming days we were taught to pass in as parameters everything needed by
a routine. This was understandable because the alternative was global data, and global data is
evil and usually painful. Objects change this situation because if you don't have something
you need, you can always ask another object to get it for you. Thus with objects you don't
pass in everything the method needs; instead you pass enough so that the method can get to
everything it needs. A lot of what a method needs is available on the method's host class. In
object-oriented programs parameter lists tend to be much smaller than in traditional
programs.
This is good because long parameter lists are hard to understand, because they become
inconsistent and difficult to use, and because you are forever changing them as you need
more data. Most changes are removed by passing objects because you are much more likely
to need to make only a couple of requests to get at a new piece of data.
Use Replace Parameter with Method when you can get the data in one parameter by making
a request of an object you already know about. This object might be a field or it might be
another parameter. Use Preserve Whole Object to take a bunch of data gleaned from an
object and replace it with the object itself. If you have several data items with no logical
object, use Introduce Parameter Object.
There is one important exception to making these changes. This is when you explicitly do
not want to create a dependency from the called object to the larger object. In those cases
unpacking data and sending it along as parameters is reasonable, but pay attention to the pain
involved. If the parameter list is too long or changes too often, you need to rethink your
dependency structure.
I don't want to sound like a wise-crack, but you should also check to make sure the data you are passing around really should be passed around: Passing stuff to a constructor (or method for that matter) smells a bit like to little emphasis on the behavior of an object.
Don't get me wrong: Methods and constructors will have a lot of parameters sometimes. But when encountered, do try to consider encapsulating data with behavior instead.
This kind of smell (since we are talking about refactoring, this horrible word seems appropriate...) might also be detected for objects that have a lot (read: any) properties or getters/setters.
If some of the constructor parameters are optional it makes sense to use a builder, which would get the required parameters in the constructor, and have methods for the optional ones, returning the builder, to be used like this:
return new Shniz.Builder(foo, bar).baz(baz).quux(quux).build();
The details of this are described in Effective Java, 2nd Ed., p. 11. For method arguments, the same book (p. 189) describes three approaches for shortening parameter lists:
Break the method into multiple methods that take fewer arguments
Create static helper member classes to represent groups of parameters, i.e. pass a DinoDonkey instead of dino and donkey
If parameters are optional, the builder above can be adopted for methods, defining an object for all parameters, setting the required ones and then calling some execute method on it
You can try to group your parameter into multiples meaningful struct/class (if possible).
I would generally lean towards the structs approach - presumably the majority of these parameters are related in some way and represent the state of some element that is relevant to your method.
If the set of parameters can't be made into a meaningful object, that's probably a sign that Shniz is doing too much, and the refactoring should involve breaking the method down into separate concerns.
I would use the default constructor and property settors. C# 3.0 has some nice syntax to do this automagically.
return new Shniz { Foo = foo,
Bar = bar,
Baz = baz,
Quuz = quux,
Fred = fred,
Wilma = wilma,
Barney = barney,
Dino = dino,
Donkey = donkey
};
The code improvement comes in simplifying the constructor and not having to support multiple methods to support various combinations. The "calling" syntax is still a little "wordy", but not really any worse than calling the property settors manually.
You haven't provided enough information to warrant a good answer. A long parameter list isn't inherently bad.
Shniz(foo, bar, baz, quux, fred, wilma, barney, dino, donkey)
could be interpreted as:
void Shniz(int foo, int bar, int baz, int quux, int fred,
int wilma, int barney, int dino, int donkey) { ...
In this case you're far better off to create a class to encapsulate the parameters because you give meaning to the different parameters in a way that the compiler can check as well as visually making the code easier to read. It also makes it easier to read and refactor later.
// old way
Shniz(1,2,3,2,3,2,1,2);
Shniz(1,2,2,3,3,2,1,2);
//versus
ShnizParam p = new ShnizParam { Foo = 1, Bar = 2, Baz = 3 };
Shniz(p);
Alternatively if you had:
void Shniz(Foo foo, Bar bar, Baz baz, Quux quux, Fred fred,
Wilma wilma, Barney barney, Dino dino, Donkey donkey) { ...
This is a far different case because all the objects are different (and aren't likely to be muddled up). Agreed that if all objects are necessary, and they're all different, it makes little sense to create a parameter class.
Additionally, are some parameters optional? Are there method override's (same method name, but different method signatures?) These sorts of details all matter as to what the best answer is.
* A property bag can be useful as well, but not specifically better given that there is no background given.
As you can see, there is more than 1 correct answer to this question. Take your pick.
If you have that many parameters, chances are that the method is doing too much, so address this first by splitting the method into several smaller methods. If you still have too many parameters after this try grouping the arguments or turning some of the parameters into instance members.
Prefer small classes/methods over large. Remember the single responsibility principle.
You can trade complexity for source code lines. If the method itself does too much (Swiss knife) try to halve its tasks by creating another method. If the method is simple only it needs too many parameters then the so called parameter objects are the way to go.
If your language supports it, use named parameters and make as many optional (with reasonable defaults) as possible.
I think the method you described is the way to go. When I find a method with a lot of parameters and/or one that is likely to need more in the future, I usually create a ShnizParams object to pass through, like you describe.
How about not setting it in all at once at the constructors but doing it via properties/setters? I have seen some .NET classes that utilize this approach such as Process class:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.FileName = "cmd";
p.StartInfo.Arguments = "/c dir";
p.Start();
I concur with the approach of moving the parameters into a parameter object (struct). Rather than just sticking them all in one object though, review if other functions use similar groups of parameters. A paramater object is more valuable if its used with multiple functions where you expect that set of parameters to change consistently across those functions. It may be that you only put some of the parameters into the new parameter object.
Named arguments are a good option (presuming a language which supports them) for disambiguating long (or even short!) parameter lists while also allowing (in the case of constructors) the class's properties to be immutable without imposing a requirement for allowing it to exist in a partially-constructed state.
The other option I would look for in doing this sort of refactor would be groups of related parameters which might be better handled as an independent object. Using the Rectangle class from an earlier answer as an example, the constructor which takes parameters for x, y, height, and width could factor x and y out into a Point object, allowing you to pass three parameters to the Rectangle's constructor. Or go a little further and make it two parameters (UpperLeftPoint, LowerRightPoint), but that would be a more radical refactoring.
It depends on what kind of arguments you have, but if they are a lot of boolean values/options maybe you could use a Flag Enum?
I think that problem is deeply tied to the domain of the problem you're trying to solve with the class.
In some cases, a 7-parameter constructor may indicate a bad class hierarchy: in that case, the helper struct/class suggested above is usually a good approach, but then you also tend to end up with loads of structs which are just property bags and don't do anything useful.
The 8-argument constructor might also indicate that your class is too generic / too all-purpose so it needs a lot of options to be really useful. In that case you can either refactor the class or implement static constructors that hide the real complex constructors: eg. Shniz.NewBaz (foo, bar) could actually call the real constructor passing the right parameters.
One consideration is which of the values would be read-only once the object is created?
Publicly writable properties could perhaps be assigned after construction.
Where ultimately do the values come from? Perhaps some values are truely external where as others are really from some configuration or global data that is maintained by the library.
In this case you could conceal the constructor from external use and provide a Create function for it. The create function takes the truely external values and constructs the object, then uses accessors only avaiable to the library to complete the creation of the object.
It would be really strange to have an object that requires 7 or more parameters to give the object a complete state and all truely being external in nature.
When a clas has a constructor that takes too many arguments, it is usually a sign that it has too many responsibilities. It can probably be broken into separate classes that cooperate to give the same functionalities.
In case you really need that many arguments to a constructor, the Builder pattern can help you. The goal is to still pass all the arguments to the constructor, so its state is initialized from the start and you can still make the class immutable if needed.
See below :
public class Toto {
private final String state0;
private final String state1;
private final String state2;
private final String state3;
public Toto(String arg0, String arg1, String arg2, String arg3) {
this.state0 = arg0;
this.state1 = arg1;
this.state2 = arg2;
this.state3 = arg3;
}
public static class TotoBuilder {
private String arg0;
private String arg1;
private String arg2;
private String arg3;
public TotoBuilder addArg0(String arg) {
this.arg0 = arg;
return this;
}
public TotoBuilder addArg1(String arg) {
this.arg1 = arg;
return this;
}
public TotoBuilder addArg2(String arg) {
this.arg2 = arg;
return this;
}
public TotoBuilder addArg3(String arg) {
this.arg3 = arg;
return this;
}
public Toto newInstance() {
// maybe add some validation ...
return new Toto(this.arg0, this.arg1, this.arg2, this.arg3);
}
}
public static void main(String[] args) {
Toto toto = new TotoBuilder()
.addArg0("0")
.addArg1("1")
.addArg2("2")
.addArg3("3")
.newInstance();
}
}
The short answer is that:
You need to group the related parameters or redesigning our model
Below example, the constructor takes 8 parameters
public Rectangle(
int point1X,
int point1Y,
int point2X,
int point2Y,
int point3X,
int point3Y,
int point4X,
int point4Y) {
this.point1X = point1X;
this.point1Y = point1Y;
this.point2X = point2X;
this.point2Y = point2Y;
this.point3X = point3X;
this.point3Y = point3Y;
this.point4X = point4X;
this.point4Y = point4Y;
}
After grouping the related parameters,
Then, the constructor will take ONLY 4 parameters
public Rectangle(
Point point1,
Point point2,
Point point3,
Point point4) {
this.point1 = point1;
this.point2 = point2;
this.point3 = point3;
this.point4 = point4;
}
public Point(int x, int y) {
this.x = x;
this.y= y;
}
Or even make the constructor smarter,
After redesigning our model
Then, the constructor will take ONLY 2 parameters
public Rectangle(
Point leftLowerPoint,
Point rightUpperPoint) {
this.leftLowerPoint = leftLowerPoint;
this.rightUpperPoint = rightUpperPoint;
}

Resources