Instantiation of classes in wrong place leads to wrong structures ... (reminder)

In OOP many times I encountered a bad structured code; just because of absence of a good recommendation on it. This is asking about one of them.
So Is this a valid/useful recommendation in OOP:
[Methods must not instantiate objects of other classes (at least the classes in the same "sub-system"); but they must be declared as fields.]
(Because using objects directly in methods - not as fields - will break useful definition path of OO things. Of course this may be an old quota; but recently I saw many codes that violates this and if this is important how can we enforce it?)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Control coupling

I'd say that one class that becomes too familiar with the internals of another class is Control Coupling. As with most things, the way to prevent one class usurping another is to have well defined interfaces that promote the correct level of abstraction, hiding unnecessary details. From a PL design perspective, the language should provide mechanisms that promote modularity.

I'm not sure, however, how the distinction between methods, fields and attributes will help matters. If you take the angle of a language like Eiffel, these three things are really just features. Indeed, the Eiffel philosophy is that making a distinction between them leads to a form of coupling - restricting the freedom to change implementation from one to the other.

And None OO Programming

Indeed! What you have pointed out here is a very precise thing to have in mind.
But I feel something else too. I feel instantiation so freely is somehow none OO way. Maybe there should be a mechanism in each class for instantiation of other classes in a certain way; not everywhere in every method. The ability to do so (freely instantiate) can rut the code and convert it to a mess quietly; without our attention.
Imagine in a method of a class you are instantiating and using 4 other classes of your package (not composing or inheriting them). What is the difference between this code and a code provided in structural languages like C?
I mean "everything is object" does not mean the language is object oriented (enough) and it lakes something. (Maybe I am adding something by myself; but I know I am pointing to something that can - and have done - bring down a code and make it hard to maintain or even useless)

Different dependencies, different language elements

If a method of a class instantiates another class, that's just another kind of dependency, and of course, you'd want your class to depend on few other classes. The rule quoted above makes such dependencies explicit by replacing the instantiates-dependency with an association and possibly a setter/getter pair. However, fields suggest a certain lifetime of the values stored in them (spanning multiple method calls), and this lifetime does not always match the intended lifetime. I see three alternatives which the rule should include:

  • Abstract Factory pattern (call a factory object which you've been given)
  • Factory Method pattern (instantiation happens in an abstract factory method)
  • Leave the instantiations as they are: for struct/record-like objects with explicitly no interesting behaviour, when the lifetime is limited to one method invocation.

Perfect Reminder

Thank you! Your comment is a perfect reminder! I was aware of using patterns (Factory Method).
Still patterns need some self-management in coding. Maybe there are tools for checking on coding conventions in a project (I have not seen one for C# yet).
The most interesting thing in my opinion is some extensions and enhancements to the language like attributes in C# and their use in extended C# ([NotNullable] attribute on an argument of a method i.e.) or the quoted code in F#, which is a type-safe meta-programming technique; still in mainstream-things we have to tag along with dirty hacks (in most cases). Patterns are clean-hacks; but my point was to enhance our tools (like Linq which is in fact a monad enhancement for list monad and came from Haskell). This is the path I like and ... it seems, to others, this is not as interesting as it is to me!
Cheers :)

Still patterns need some

Still patterns need some self-management in coding. Maybe there are tools for checking on coding conventions in a project (I have not seen one for C# yet).

Have you looked at FxCop? Implementing a "members can't create local ref type variables" should be possible. I actually thougt about implementing a [nonnullable] attribute for arguments, fields, properties and return values myself (but I never had enough time to do it...) I think it would be possible, if you accept some false positives. (After all, C# does ensure values types are initialized before they are used)

Keywords

Dependency Injection. Inversion of Control. :-)

Whaa?

Forgive my ignorance, but I do not know what you are advocating with "Methods must not instantiate objects of other classes". It appears to be a obfuscating rule rather than good design rule. What do you mean by "but they must be declared as fields"? Did you mean method parameter?

Can you give a sample of the bad code?

Here is where I see methods instantiating as useful:

  • The myParser.parse() instance method generates a whole plethora of token objects in a parse tree. (Factory Method?)
  • "struct/record-like objects" as KonradAnton mentioned, but last an indeterminate amount of time, as they are usually cached

Thanks

Law of Demeter?

The suggestion in the initial post sounds like a stripped down version of the so-called Law of Demeter (see here for a paper introducing the law)... advice that I've always considered a bit dubious--especially when formulated as a "law". The intent is to reduce coupling--a given class A is already coupled, in some fashion, to any other class it is composed of, inherits, or takes as method arguments; the LoD essentially says you should avoid coupling to additional classes beyond these, by not invoking methods on them. Reducing coupling is a good idea, but I'm of the multiparadigm view that a the interface of a type or module need not be limited to the methods of a particular class--choosing to couple to additional classes in your system is OK by me. And certainly, many ways to get around the LoD is to simply make the coupling explicit by expanding the class definition to include new methods which DO mention the additional types in their signatures. Sometimes this can be useful (if it abstracts a common operation); at other times it just clutters up an interface.

LoD good for whom?

I think when I have to maintain code I like the LoD because it means things can more easily be swapped around. But when I'm writing code in some language that doesn't help me do delegation, then I don't like the required labor so much.

LoD? Maybe

I agree the LoD can thoroughly destroy a clean interface. I like my packages with simple interfaces so they are a delightc to use as libraries. Unfortunately there is always the one "magic" object that digs deep into the package's objects' internals to implement functionality.

This happens when you are building some non-well founded (recursively defined) service. I find non-well founded designs cleaner on the outside (where it matters) and dirty on the inside.

The relationship between

The relationship between object-oriented design and coalgebraic specification... </pondering>