The Law of Demeter does not prevent passing objects into class constructors. However, it does forbid getting that same object back later and calling a method on it to get a scalar value out. Instead, a proxy method is supposed to be created that returns the scalar value instead. My question is, why is it acceptable to pass an object into a class constructor but unacceptable to get the same object back later and pull a value from it?
Because the Law of Demeter says that you should not design the external interface of an object to make it look as if it is composed of certain other objects with known interfaces, that clients can just grab hold of and access.
You pass an object into the constructor to tell your new object how to behave, but it is none of your business whether the object keeps that parameter object around, or keeps a copy of it, or just looks at it once and forgets it ever existed. By having a getMyParameterBack method, you've committed all future implementations to be able to produce that whole object on demand, and all clients to couple with two interfaces instead of one.
For example, if you pass in a URL parameter to your HTTPRequest object's constructor, then that doesn't mean HTTPRequest should have a getURL method which returns a URL object on which the caller is then expected to call getProtocol, getQueryString, etc. If someone who has an HTTPRequest object might want to know the protocol of the request, they should (the Law says) find out by calling getProtocol on the object they have, not on some other object that they happen to know HTTPRequest is storing internally.
The idea is to reduce coupling - without the Law of Demeter, the user has to know the interface to HTTPRequest and URL in order to get the protocol. With the Law, they only need the interface to HTTPRequest. And HTTPRequest.getProtocol() clearly can return "http" without needing some URL object to be involved in the discussion.
The fact that sometimes the user of the request object happens to be the one who created it, and therefore is using the URL interface too in order to pass the parameter, is neither here nor there. Not all users of HTTPRequest objects will have created them themselves. So clients which are entitled under the Law to access the URL because they created it themselves, can do it that way rather than grabbing it back off the Request. Clients which did not create the URL can't.
Personally I think the Law of Demeter as usually stated in simple form, is cracked. Are they seriously saying that if my object has a string Name field, and I want to know whether the Name contains any non-ASCII characters, then I must either define a NameContainsNonASCIICharacters method on my object instead of looking at the string itself, or else add a visitName function to the class taking a callback function in order to work around the restriction by ensuring that the string is a parameter to a function I've written? That doesn't change the coupling at all, it just replaces getter methods with visitor methods. Should every class which returns an integer have a full set of arithmetic operations, in case I want to manipulate the return value? getPriceMultipliedBy(int n)? Surely not.
What it is useful for, is that when you break it you can ask yourself why you're breaking it, and whether you could design a better interface by not breaking it. Frequently you can, but really it depends what kinds of objects you're talking about. Certain interfaces can safely be coupled against vast swathes of code - things like integer, string, and even URL, which represent widely-used concepts.
JP's answer is pretty good, so this is just a supplement, not a disagreement or other replacement.
The way I understand this heuristic is that a call to A shouldn't break because of class B changing. So if you chain your calls with a.b.foo(), then A's interface becomes dependent upon B's, violating the rule. Instead, you're supposed to call a.BFoo(), which calls b.foo() for you.
This is a good rule of thumb, but it can lead to awkward code that doesn't really address the dependency so much as enshrine it. Now A has to offer BFoo forever, even when B no longer offers Foo. Not much of an improvement and it would be arguably better in at least some cases if changes to B broke the caller that wants Foo, not B itself.
I would also add that, strictly speaking, this rule is broken constantly for a certain group of ubiquitous classe, such as string. Perhaps it's acceptable to decide which classes are likewise ubiquitous within a particular layer of an application and freely ignore Demeter's "Rule" for them.
The idea is that you only talk to your immediate friends. So, you don't do this ...
var a = new A();
var x = a.B.doSomething();
Instead you do this ...
var a = new A();
var x = a.doSomething(); // where a.doSomething might call b.doSomething();
It has it's advantages, as things become simpler for callers (Car.Start() versus Car.Engine.Start()), but you get lots of little wrapping methods. You can also use the Mediator pattern to mitigate this type of "violation".
Related
In oop we seek to encapsulation. We try not to expose internal state via getters or by public fields, only expose methods.
So far so good.
In situation when we would like to operate on multiple Entities we introduce Service.
But how this service can operate freely on these entities?
If all (both Service and Entities) were in the same package, Entities could expose package private methods or fields and Service could use them, preserving encapsulation. But what when Entities and Service are from different packages? It seems that Entities should either expose public getters (first step to anemic model and leackage of logic from Entities), or public methods executing logic that is specific to the needs of service, possibly introduced only by requirements of this service - also seems bad. How to tackle this?
In the context of OO, the most important thing for you to understand is that objects respond to messages, and that in OOP in particular, methods are how these responses are implemented.
For example, imagine you have a Person object to which you (as the programmer) have assigned the responsibility to respond to the "grow" message. Generally, you would implement that as a Person.grow() method, like this.
class Person {
int age;
public void grow() { this.age++; }
}
This seems fairly obvious, but you must note that from the message sender's perspective, how Person object reacts is meaningless. For all it cares, the method Person.grow() could be triggering a missile launch, and it would not matter because some other object (or objects) could be responding in the right way (for example, a UI component updating itself on the screen). However, you decided that when the Person object handles the "grow" message, it must increment the value of its age attribute. This is encapsulation.
So, to address your concern, "public methods executing logic that is specific to the needs of service, possibly introduced only by requirements of this service - also seems bad", it is not bad at all because you are designing the entities to respond to messages from the services in specific ways to match the requirements of your application. The important thing to bear in mind is that the services do not dictate how the entities behave, but rather the entities respond in their own way to requests from the services.
Finally, you might be asking yourself: how do entities know that they need to respond to certain messages? This is easy to answer: YOU decide how to link messages to responses. In other words, you think about the requirements of your application (what "messages" will be sent by various objects) and how they will be satisfied (how and which objects will respond to messages).
In situation when we would like to operate on multiple Entities we introduce Service.
No we don't. Well, I guess some people do, but the point is they shouldn't.
In object-orientation, we model a particular problem domain. We don't (again, shouldn't) discriminate based on what amount of other objects a single object operates. If I have to model an Appointment and a collection of Appointment I don't introduce an AppointmentService, I introduce a Schedule or Timetable, or whatever is appropriate for the domain.
The distinction of Entity and Service is not domain-conform. It is purely technical and most often a regression into procedural thinking, where an Entity is data and the Service is a procedure to act on it.
DDD as is practiced today is not based on OOP, it just uses object syntax. One clear indication is that in most projects entities are directly persisted, even contain database ids or database-related annotations.
So either do OOP or do DDD, you can't really do both. Here is a talk of mine (talk is german but slides are in english) about OO and DDD.
I don't see the usage of getters as a step towards an anaemic model. Or at least, as everything in programming, it depends.
Downside of anaemic model is that every component accessing the object can mutate it without any enforcing of its invariants (opening to possible inconsistency in data), it can be done easily using the setter methods.
(I will use the terms command and query to indicate methods that modify the state of the objects and methods that just return data without changing anything)
The point of having an aggregate/entity is to enforce the object invariants, so it exposes "command" methods that don't reflect the internal structure of the object, but instead are "domain oriented" (using the "ubiquitous language" for their naming), exposing its "domain behavior" (an avoidance of get/set naming is suggested because they are standard naming for representing the object internal structure).
This is for what concern the set methods, what about get?
As set methods can be seen as "command" of the aggregate, you can see the getters as "query" methods used to ask data to the aggregate. Asking data to an aggregate is totally fine, if this doesn't break the responsability of the aggregate of enforcing invariants. This means that you should watch out to what the query method returns.
If the query method result is a value object, so, immutable, it is totally fine to have it. In this way who query the aggregate has in return something that can be only read.
So you could have query methods doing calculation using the object internal state (eg. A method int missingStudents() that calculate the number of missing student for a Lesson entity that has the totalNumber of students and a List<StudentId> in its internal state), or simple methods like List<StudentId> presentStudent() that just returns the list in its internal state, but what change from a List<StudentId> getStudents() its just the name).
So if the get method return something that is immutable who use it can't break the invariants of the aggregate.
If the method returns a mutable object that is part of the aggregate state, whoever access the object can query for that object and now can mutate something that stays inside the aggregate without passing for the right command methods, skipping invariants check (unless it is something wanted and managed).
Other possibility is that the object is created on the fly during the query and is not part of the aggregate state, so if someone access it, also if it is mutable, the aggregate is safe.
In the end, get and set methods are seen as an ugly thing if you are a ddd extremist, but sometimes they can also be useful being a standard naming convention and some libraries work on this naming convention, so I don't see them bad, if they don't break the aggregate/entity responsibilities.
As last thing, when you say In situation when we would like to operate on multiple Entities we introduce Service., this is true, but also a service should operate (mutate, save) on a single aggregate, but this is another topic 😊.
I have a class which represents a set of numbers. The constructor takes three arguments: startValue, endValue and stepSize.
The class is responsible for holding a list containing all values between start and end value taking the stepSize into consideration.
Example: startValue: 3, endValue: 1, stepSize = -1, Collection = { 3,2,1 }
I am currently creating the collection and some info strings about the object in the constructor. The public members are read only info strings and the collection.
My constructor does three things at the moment:
Checks the arguments; this could throw an exception from the constructor
Fills values into the collection
Generates the information strings
I can see that my constructor does real work but how can I fix this, or, should I fix this? If I move the "methods" out of the constructor it is like having init function and leaving me with an not fully initialized object. Is the existence of my object doubtful? Or is it not that bad to have some work done in the constructor because it is still possible to test the constructor because no object references are created.
For me it looks wrong but it seems that I just can't find a solution. I also have taken a builder into account but I am not sure if that's right because you can't choose between different types of creations. However single unit tests would have less responsibility.
I am writing my code in C# but I would prefer a general solution, that's why the text contains no code.
EDIT: Thanks for editing my poor text (: I changed the title back because it represents my opinion and the edited title did not. I am not asking if real work is a flaw or not. For me, it is. Take a look at this reference.
http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/
The blog states the problems quite well. Still I can't find a solution.
Concepts that urge you to keep your constructors light weight:
Inversion of control (Dependency Injection)
Single responsibility principle (as applied to the constructor rather than a class)
Lazy initialization
Testing
K.I.S.S.
D.R.Y.
Links to arguments of why:
How much work should be done in a constructor?
What (not) to do in a constructor
Should a C++ constructor do real work?
http://misko.hevery.com/code-reviewers-guide/flaw-constructor-does-real-work/
If you check the arguments in the constructor that validation code can't be shared if those arguments come in from any other source (setter, constructor, parameter object)
If you fill values into the collection or generate the information strings in the constructor that code can't be shared with other constructors you may need to add later.
In addition to not being able to be shared there is also being delayed until really needed (lazy init). There is also overriding thru inheritance that offers more options with many methods that just do one thing rather then one do everything constructor.
Your constructor only needs to put your class into a usable state. It does NOT have to be fully initialized. But it is perfectly free to use other methods to do the real work. That just doesn't take advantage of the "lazy init" idea. Sometimes you need it, sometimes you don't.
Just keep in mind anything that the constructor does or calls is being shoved down the users / testers throat.
EDIT:
You still haven't accepted an answer and I've had some sleep so I'll take a stab at a design. A good design is flexible so I'm going to assume it's OK that I'm not sure what the information strings are, or whether our object is required to represent a set of numbers by being a collection (and so provides iterators, size(), add(), remove(), etc) or is merely backed by a collection and provides some narrow specialized access to those numbers (such as being immutable).
This little guy is the Parameter Object pattern
/** Throws exception if sign of endValue - startValue != stepSize */
ListDefinition(T startValue, T endValue, T stepSize);
T can be int or long or short or char. Have fun but be consistent.
/** An interface, independent from any one collection implementation */
ListFactory(ListDefinition ld){
/** Make as many as you like */
List<T> build();
}
If we don't need to narrow access to the collection, we're done. If we do, wrap it in a facade before exposing it.
/** Provides read access only. Immutable if List l kept private. */
ImmutableFacade(List l);
Oh wait, requirements change, forgot about 'information strings'. :)
/** Build list of info strings */
InformationStrings(String infoFilePath) {
List<String> read();
}
Have no idea if this is what you had in mind but if you want the power to count line numbers by twos you now have it. :)
/** Assuming information strings have a 1 to 1 relationship with our numbers */
MapFactory(List l, List infoStrings){
/** Make as many as you like */
Map<T, String> build();
}
So, yes I'd use the builder pattern to wire all that together. Or you could try to use one object to do all that. Up to you. But I think you'll find few of these constructors doing much of anything.
EDIT2
I know this answer's already been accepted but I've realized there's room for improvement and I can't resist. The ListDefinition above works by exposing it's contents with getters, ick. There is a "Tell, don't ask" design principle that is being violated here for no good reason.
ListDefinition(T startValue, T endValue, T stepSize) {
List<T> buildList(List<T> l);
}
This let's us build any kind of list implementation and have it initialized according to the definition. Now we don't need ListFactory. buildList is something I call a shunt. It returns the same reference it accepted after having done something with it. It simply allows you to skip giving the new ArrayList a name. Making a list now looks like this:
ListDefinition<int> ld = new ListDefinition<int>(3, 1, -1);
List<int> l = new ImmutableFacade<int>( ld.buildList( new ArrayList<int>() ) );
Which works fine. Bit hard to read. So why not add a static factory method:
List<int> l = ImmutableRangeOfNumbers.over(3, 1, -1);
This doesn't accept dependency injections but it's built on classes that do. It's effectively a dependency injection container. This makes it a nice shorthand for popular combinations and configurations of the underlying classes. You don't have to make one for every combination. The point of doing this with many classes is now you can put together whatever combination you need.
Well, that's my 2 cents. I'm gonna find something else to obsess on. Feedback welcome.
As far as cohesion is concerned, there's no "real work", only work that's in line (or not) with the class/method's responsibility.
A constructor's responsibility is to create an instance of a class. And a valid instance for that matter. I'm a big fan of keeping the validation part as intrinsic as possible, so that you can see the invariants every time you look at the class. In other words, that the class "contains its own definition".
However, there are cases when an object is a complex assemblage of multiple other objects, with conditional logic, non-trivial validation or other creation sub-tasks involved. This is when I'd delegate the object creation to another class (Factory or Builder pattern) and restrain the accessibility scope of the constructor, but I think twice before doing it.
In your case, I see no conditionals (except argument checking), no composition or inspection of complex objects. The work done by your constructor is cohesive with the class because it essentially only populates its internals. While you may (and should) of course extract atomic, well identified construction steps into private methods inside the same class, I don't see the need for a separate builder class.
The constructor is a special member function, in a way that it constructor, but after all - it is a member function. As such, it is allowed to do things.
Consider for example c++ std::fstream. It opens a file in the constructor. Can throw an exception, but doesn't have to.
As long as you can test the class, it is all good.
It's true, a constructur should do minimum of work oriented to a single aim - successful creaation of the valid object. Whatever it takes is ok. But not more.
In your example, creating this collection in the constructor is perfectly valid, as object of your class represent a set of numbers (your words). If an object is set of numbers, you should clearly create it in the constructor! On the contrary - the constructur does not perform what it is made for - a fresh, valid object construction.
These info strings call my attention. What is their purpose? What exactly do you do? This sounds like something periferic, something that can be left for later and exposed through a method, like
String getInfo()
or similar.
If you want to use Microsoft's .NET Framework was an example here, it is perfectly valid both semantically and in terms of common practice, for a constructor to do some real work.
An example of where Microsoft does this is in their implementation of System.IO.FileStream. This class performs string processing on path names, opens new file handles, opens threads, binds all sorts of things, and invokes many system functions. The constructor is actually, in effect, about 1,200 lines of code.
I believe your example, where you are creating a list, is absolutely fine and valid. I would just make sure that you fail as often as possible. Say if you the minimum size higher than the maximum size, you could get stuck in an infinite loop with a poorly written loop condition, thus exhausting all available memory.
The takeaway is "it depends" and you should use your best judgement. If all you wanted was a second opinion, then I say you're fine.
It's not a good practice to do "real work" in the constructor: you can initialize class members, but you shouldn't call other methods or do more "heavy lifting" in the constructor.
If you need to do some initialization which requires a big amount of code running, a good practice will be to do it in an init() method which will be called after the object was constructed.
The reasoning for not doing heavy lifting inside the constructor is: in case something bad happens, and fails silently, you'll end up having a messed up object and it'll be a nightmare to debug and realize where the issues are coming from.
In the case you describe above I would only do the assignments in the constructor and then, in two separate methods, I would implement the validations and generate the string-information.
Implementing it this way also conforms with SRP: "Single Responsibility Principle" which suggests that any method/function should do one thing, and one thing only.
Given some type as follows:
class Thing {
getInfo();
isRemoteThing();
getRemoteLocation();
}
The getRemoteLocation() method only has a defined result if isRemoteThing() returns true. Given that most Things are not remote, is this an acceptable API? The other option I see is to provide a RemoteThing subclass, but then the user needs a way to cast a Thing to a RemoteThing if necessary, which just seems to add a level of indirection to the problem.
Having an interface include members which are usable on some objects that implement the interface but not all of them, and also includes a query method to say which interface members will be useful, is a good pattern in cases where something is gained by it.
Examples of reasons where it can be useful:
If it's likely than an interface member will be useful on some objects but not other instances of the same type, this pattern may be the only one that makes sense.
If it's likely that a consumer may hold references to a variety of objects implementing the interface, some of which support a particular member and some of which do not, and if it's likely that someone with such a collection would want to use the member on those instances which support it, such usage will be more convenient if all objects implement an interface including the member, than if some do and some don't. This is especially true for interface members like IDisposable.Dispose whose purpose is to notify the implementation of something it may or may not care about (e.g. that nobody needs it anymore and it may be abandoned without further notice), and ask it to do whatever it needs to as a consequence (in many cases nothing). Blindly calling Dispose on an IEnumerable<T> is faster than checking whether an implementation of IEnumerable also implements IDisposable. Not only the unconditional call faster than checking for IDisposable and then calling it--it's faster than checking whether an object implements IDisposable and finding out that it doesn't.
In some cases, a consumer may use a field to hold different kinds of things at different times. As an example, it may be useful to have a field which at some times will hold the only extant reference to a mutable object, and at other times will hold a possibly-shared reference to an immutable object. If the type of the field includes mutating methods (which may or may not work) as well as a means of creating a new mutable instance with data copied from an immutable one, code which receives an object and might want to mutate the data can store a reference to the passed-in object. If and when it wants to mutate the data, it can overwrite the field with a reference to a mutable copy; if it never ends up having to mutate the data, however, it can simply use the passed-in immutable object and never bother copying it.
The biggest disadvantage of having interfaces include members that aren't always useful is that it imposes more work on the implementers. Thus, people writing interfaces should only include members whose existence could significantly benefit at least some consumers of almost every class implementing the interface.
Why should this not be acceptable? It should, however, be clearly documented. If you look at the .net class libraries or the JDK, there are collection interfaces defining methods to add or delete items, but there are unmodifiable classes implementing these interfaces. It is a good idea in this case - as you did - to provide a method to query the object if it has some capabilities, as this helps you avoid exceptions in the case that the method is not appropriate.
OTOH, if this is an API, it might be more appropriate to use an interface than a class.
I often see two conflicting strategies for method interfaces, loosely summarized as follows:
// Form 1: Pass in an object.
double calculateTaxesOwed(TaxForm f) { ... }
// Form 2: Pass in the fields you'll use.
double calculateTaxesOwed(double taxRate, double income) { ... }
// use of form 1:
TaxForm f = ...
double payment = calculateTaxesOwed(f);
// use of form 2:
TaxForm f = ...
double payment = calculateTaxesOwed(f.getTaxRate(), f.getIncome());
I've seen advocates for the second form, particularly in dynamic languages where it may be harder to evaluate what fields are being used.
However, I much prefer the first form: it's shorter, there is less room for error, and if the definition of the object changes later you won't necessarily need to update method signatures, perhaps just change how you work with the object inside the method.
Is there a compelling general case for either form? Are there clear examples of when you should use the second form over the first? Are there SOLID or other OOP principles I can point to to justify my decision to use one form over the other? Do any of the above answers change if you're using a dynamic language?
In all honesty it depends on the method in question.
If the method makes sense without the object, then the second form is easier to re-use and removes a coupling between the two classes.
If the method relies on the object then fair enough pass the object.
There is probably a good argument for a third form where you pass an interface designed to work with that method. Gives you the clarity of the first form with the flexibility of the second.
It depends on the intention of your method.
If the method is designed to work specifically with that object and only that object, pass the object. It makes for a nice encapsulation.
But, if the method is more general purpose, you will probably want to pass the parameters individually. That way, the method is more likely to be reused when the information is coming from another source (i.e. different types of objects or other derived data).
I strongly recommend the second solution - calculateTaxesOwed() calculates some data, hence needs some numerical input. The method has absolutly nothing to do with the user interface and should in turn not consum a form as input, because you want your business logic separated from your user interface.
The method performing the calculation should (usualy) not even belong to the same modul as the user interface. In this case you get a circular dependency because the user interface requires the business logic and the business logic requires the user interface form - a very strong indication that something is wrong (but could be still solved using interface based programming).
UPDATE
If the tax form is not a user interface form, things change a bit. In this case I suggest to expose the value using a instance method GetOwedTaxes() or instance property OwedTaxes of the TaxForm class but I would not use a static method. If the calculation can be reused elsewhere, one could still create a static helper method consuming the values, not the form, and call this helper method from within the instance method or property.
I don't think it really matters. You open yourself to side effects if you pass in the Object as it might be mutated. This might however be what you want. To mitigate this (and to aid testing) you are probably better passing the interface rather than the concrete type. The benefit is that you don't need to change the method signature if you want to access another field of the Object.
Passing all the parameters makes it clearer what the type needs, and might make it easier to test (though if you use the interface this is less of a benefit). But you will have more refactoring.
Judge each situation on its merits and pick the least painful.
Passing just the arguments can be easier to unit test, as you don't need to mock up entire objects full of data just to test functionality that is essentially just static calculation. If there are just two fields being used, of the object's many, I'd lean towards just passing those fields, all else being equal.
That said, when you end up with six, seven or more fields, it's time to consider passing either the whole object or a subset of the fields in a "payload" class (or struct/dictionary, depending on the language's style). Long method signatures are usually confusing.
The other option is to make it a class method, so you don't have to pass anything. It's less convenient to test, but worth considering when your method is only ever used on a TaxForm object's data.
I realize that this is largely an artifact of the example used and so it may not apply in many real-world cases, but, if the function is tied so strongly to a specific class, then shouldn't it be:
double payment = f.calculateTaxesOwed;
It seems more appropriate to me that a tax document would carry the responsibility itself for calculating the relevant taxes rather than having that responsibility fall onto a utility function, particularly given that different tax forms tend to use different tax tables or calculation methods.
One advantage of the first form is
Abstraction - programming to an interface rather than implementation. It makes the maintainance of your code easier in the long run becuase you may change the implementation of TaxForm without affecting the client code as long as the interface of TaxForm does not change.
This is the same as the "Introduce Parameter Object" from Martin Fowler's book on refactoring. Fowler suggests that you perform this refactoring if there are a group of parameters that tend to be passed together.
If you believe in the Law of Demeter, then you would favor passing exactly what is needed:
http://en.wikipedia.org/wiki/Law_of_Demeter
http://www.c2.com/cgi/wiki?LawOfDemeter
Separation of UI and Data to be manipulated
In your case, you are missing an intermediate class, say, TaxInfo, representing the entity to be taxed. The reason is that UI (the form) and business logic (how tax rate is calculated) are on two different "change tracks", one changes with presentation technology ("the web", "The web 2.0", "WPF", ...), the other changes with legalese. Define a clear interface between them.
General discussion, using an example:
Consider a function to create a bitmap for a business card. Is the purpose of the function
(1) // Formats a business card title from first name and last name
OR
(2) // Formats a businnes card title from a Person record
The first option is more generic, with a weaker coupling, which is generally preferrable. However, In many cases less robust against change requests - e.g. consider "case 2017: add persons Initial to business card".
Changing the implementation (adding person.Initial) is usually easier and faster than changing the interface.
The choice is ultimately what type of changes you expect: is it more likely that more information from a Personrecord is required, or is it more likely that you want to create business card titles for other data structures than Person?
If that is "undecided", anfd you can't opf for purpose (1) or (2) I'd rather go with (2), for syntactic cleanliness.
If I was made to choose one of the two, I'd always go with the second one - what if you find that you (for whatever reason) need to caculate the taxes owed, but you dont have an instance of TaxForm?
This is a fairly trivial example, however I've seen cases where a method doing a relatively simple task had complex inputs which were difficult to create, making the method far more difficult to use than it should have been. (The author simply hadn't considered that other people might want to use that method!)
Personally, to make the code more readable, I would probbaly have both:
double calculateTaxesOwed(TaxForm f)
{
return calculateTaxesOwed(f.getTaxRate(), f.getIncome());
}
double calculateTaxesOwed(double taxRate, double income) { ... }
My rule of thumb is to wherever possible have a method that takes exactly the input it needs - its very easy to write wrapper methods.
Personally, I'll go with #2 since it's much more clear of what it is that the method need. Passing the TaxForm (if it is what I think it is, like a Windows Form) is sort of smelly and make me cringe a little (>_<).
I'd use the first variation only if you are passing a DTO specific to the calculation, like IncomeTaxCalculationInfo object which will contain the TaxRate and Income and whatever else needed to calculate the final result in the method, but never something like a Windows / Web Form.
Let's say you have a Person object and it has a method on it, promote(), that transforms it into a Captain object. What do you call this type of method/interaction?
It also feels like an inversion of:
myCaptain = new Captain(myPerson);
Edit: Thanks to all the replies. The reason I'm coming across this pattern (in Perl, but relevant anywhere) is purely for convenience. Without knowing any implementation deals, you could say the Captain class "has a" Person (I realize this may not be the best example, but be assured it isn't a subclass).
Implementation I assumed:
// this definition only matches example A
Person.promote() {
return new Captain(this)
}
personable = new Person;
// A. this is what i'm actually coding
myCaptain = personable.promote();
// B. this is what my original post was implying
personable.promote(); // is magically now a captain?
So, literally, it's just a convenience method for the construction of a Captain. I was merely wondering if this pattern has been seen in the wild and if it had a name. And I guess yeah, it doesn't really change the class so much as it returns a different one. But it theoretically could, since I don't really care about the original.
Ken++, I like how you point out a use case. Sometimes it really would be awesome to change something in place, in say, a memory sensitive environment.
A method of an object shouldn't change its class. You should either have a member which returns a new instance:
myCaptain = myPerson->ToCaptain();
Or use a constructor, as in your example:
myCaptain = new Captain(myPerson);
I would call it a conversion, or even a cast, depending on how you use the object. If you have a value object:
Person person;
You can use the constructor method to implicitly cast:
Captain captain = person;
(This is assuming C++.)
A simpler solution might be making rank a property of person. I don't know your data structure or requirements, but if you need to something that is trying to break the basics of a language its likely that there is a better way to do it.
You might want to consider the "State Pattern", also sometimes called the "Objects for States" pattern. It is defined in the book Design Patterns, but you could easily find a lot about it on Google.
A characteristic of the pattern is that "the object will appear to change its class."
Here are some links:
Objects for States
Pattern: State
Everybody seems to be assuming a C++/Java-like object system, possibly because of the syntax used in the question, but it is quite possible to change the class of an instance at runtime in other languages.
Lisp's CLOS allows changing the class of an instance at any time, and it's a well-defined and efficient transformation. (The terminology and structure is slightly different: methods don't "belong" to classes in CLOS.)
I've never heard a name for this specific type of transformation, though. The function which does this is simply called change-class.
Richard Gabriel seems to call it the "change-class protocol", after Kiczales' AMOP, which formalized as "protocols" many of the internals of CLOS for metaprogramming.
People wonder why you'd want to do this; I see two big advantages over simply creating a new instance:
faster: changing class can be as simple as updating a pointer, and updating any slots that differ; if the classes are very similar, this can be done with no new memory allocations
simpler: if a dozen places already have a reference to the old object, creating a new instance won't change what they point to; if you need to update each one yourself, that could add a lot of complexity for what should be a simple operation (2 words, in Lisp)
That's not to say it's always the right answer, but it's nice to have the ability to do this when you want it. "Change an instance's class" and "make a new instance that's similar to that one" are very different operations, and I like being able to say exactly what I mean.
The first interesting part would be to know: why do you want/need an object changes its class at runtime?
There are various options:
You want it to respond differently to some methods for a given state of the application.
You might want it to have new functionality that the original class don't have.
Others...
Statically typed languages such as Java and C# don't allow this to happen, because the type of the object should be know at compile time.
Other programming languages such as Python and Ruby may allow this ( I don't know for sure, but I know they can add methods at runtime )
For the first option, the answer given by Charlie Flowers is correct, using the state patterns would allow a class behave differently but the object will have the same interface.
For the second option, you would need to change the object type anyway and assign it to a new reference with the extra functionality. So you will need to create another distinct object and you'll end up with two different objects.