From: Alexandr Savinov on
topmind schrieb:
> Johan Stuyts wrote:
>>> Person peter = new Person();
>>> peter.setName('Peter');
>>> peter.setBirthPlace('....
>>> ...
>>>
>>> Are there any platterns, suggestion or anti-plattern related to this
>>> problem?
>> You can use a separate object to hold the parameters for the constructor:
>> PersonCreationParameters params = new PersonCreationParameters();
>> params.setName('Peter');
>> params.setBirthPlace('...');
>> // Set required and/or override optional fields here
>> Person peter = new Person(params);
>>
>> The advantages of this solution are:
>> - the parameters object can set optional values to their default values
>> when it is created. Class 'Person' can simply copy these values without
>> having to check whether they are 'null' or a special 'use the default'
>> value.
>> - If you need another field, and it is optional, you do not break existing
>> client code. Just add the field to the parameters object. No changes have
>> to be made to existing client code.
>>
>> Johan
>
>
> Rather than create a whole new class just for parameters, perhaps
> attributes can be set and then have a "validate" or "submit" method:
>
> Person peter = new Person();
> peter.setName('Peter');
> peter.setBirthPlace('....');
> peter.setMoreAttributesEtc(...);
> peter.save();

It is an anti-pattern (using a set of setters as a substitute for
constructor parameters).

--
http://conceptoriented.com
From: howa on
> It is an anti-pattern (using a set of setters as a substitute for
> constructor parameters).
>
> --http://conceptoriented.com

i agree with you. it is anti-pattern. but consider 30 parametes
constructor, it is also easy to make mistake....

From: H. S. Lahman on
Responding to Howa...

I basically agreed with the others, but not quite as strongly...

> for example, a Person class, I need to create a person using, e.g.
>
> Person peter = new Person('Peter', '....)
>
> the object creation might involved over 30 parameters, the advantage
> is this call is atomic, rather than something like, e.g.

Needing 30 parameters implies the object has 30 knowledge attributes.
That's a lot of knowledge responsibilities for an object and any
reviewer is going to want a very good reason to justify it.

In the OO paradigm objects define one level of logical indivisibility.
The objects of a subsystem represent logically indivisible units of
identity at the containing subsystem's level of abstraction. The
corollaries to indivisibility are simplicity and cohesion. So one seeks
to abstract simple, cohesive objects that have relatively few
properties. Often that requires recognizing problem space delegation
(subdivision of responsibilities) in terms of things like different
roles that the entity plays in the solution.

Having said that, multiple knowledge responsibilities are much less of a
problem that multiple behavior responsibilities. An object with a dozen
different behavior responsibilities is certainly too complex and should
be broken up. That's because behaviors describe an overall
functionality or subject matter for which the object is responsible and
that overall functionality should be narrowly defined in the subsystem
context to ensure good maintainability. IOW, it is basic separation of
concerns to manage complexity (aka divide-and-conquer). The OO paradigm
just does it differently than traditional functional decomposition by
typing indivisible behaviors together at the object level based on
problem space identity.

Knowledge attributes, OTOH, are inherently static and only indirectly
reflect particular business rules and policies (i.e., the business rules
and policies live in the behaviors that set the knowledge values). It
is also possible for a single behavior responsibility to need to chew on
a lot of data. So having a lot of knowledge responsibilities is
suspicious but not necessarily dangerous. The key criteria is cohesion
of the knowledge attributes.

Perhaps more important, it is often advantage to express the invariants
of the problem space in generic code while expressing detailed
situational differences in configuration data that parameterizes
behavior. That can greatly reduce program size while improving
reliability and maintainability. But to do that one deliberately
expresses aspects of the problem in terms of knowledge attributes, which
necessarily increases the number of such attributes. So one /expects/
more knowledge responsibilities than behavior responsibilities in a pure
counting sense.

However, as Stuyts suggested, a common solution is to isolate large
amounts of data in its own dumb data holder object that has no intrinsic
behavior responsibilities. Such objects are known as "specification
objects" because their data values specify how other objects' behavior
should execute through their values. (See the category on Invariants and
Parametric Polymorphism in my blog.) Such isolation in specification
objects tends to provide more control over the data and, consequently,
better maintainability.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



From: topmind on

howa wrote:
> > It is an anti-pattern (using a set of setters as a substitute for
> > constructor parameters).
> >
> > --http://conceptoriented.com
>
> i agree with you. it is anti-pattern. but consider 30 parametes
> constructor, it is also easy to make mistake....

Each has their advantages and disadvantages. My rule of thumb is that
more than 6 or 7 positional parameters is a yellow alert to explore
different approches, such as set/get's or an associative array (map).

-T-

From: Alexandr Savinov on
howa schrieb:
>> It is an anti-pattern (using a set of setters as a substitute for
>> constructor parameters).
>>
>> --http://conceptoriented.com
>
> i agree with you. it is anti-pattern. but consider 30 parametes
> constructor, it is also easy to make mistake....
>

Equivalently, you might define a structure with these parameters as
fields and then pass it *by-value* as only one initialization parameter.

If you define a class with constructor parameters as fields and then
pass it *by-reference* then you will get similar yet different
situation. (In OOP however the difference will hardly be visible.)

--
http://conceptoriented.com