[
https://issues.apache.org/jira/browse/NUMBERS-123?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16876562#comment-16876562
]
Heinrich Bohne commented on NUMBERS-123:
----------------------------------------
bq. What about adding a flag to the constructor?
I also considered this possibility, but for some reason, which I'm not sure I
understand myself, but which I'll try to explain, I find the notion of a
constructor that denies (or optionally delegates) the responsibility of
ensuring the validity of the values to which it initializes the fields
alienating. And unless {{equals(Object)}} and {{hashCode()}} reduce the
numerator and denominator themselves, having the fields set to non-reduced
values breaks the class (and I guess the amount of code relying on the sign
being held by the numerator and not the denominator is much greater). After
all, the constructor is the ultimate instance that performs the initialization
in the end, and moving the validation of the arguments outside the
responsibility of the constructor makes the constructor, in a way, not a "unit"
anymore, because the correctness of its functionality, on which the integrity
of the whole object about to be created hinges, now depends on how the
constructor is invoked.
But I'm not sure if this is even relevant. Maybe the reason I find the original
design with the three constructors preferable is that, in the end, the only
functionality that was explicitly "duplicated" between
{{BigFraction(BigInteger, BigInteger)}} and the two other former constructors
was the actual initialization of the fields. No other code was duplicated
between the constructors, and still, all three constructors yielded numerators
and denominators in reduced form, with the sign being held by the numerator and
a non-zero denominator, because the three constructors were so fundamentally
different from each other.
So it somehow seems as if the constructor {{BigFraction(BigInteger,
BigInteger)}} only "won" against the other two constructors because it accepts
two arguments whose functions correspond directly to the fields that need to be
initialized. But this does not automatically mean that invoking the constructor
with the "results" of the other two former constructors makes sense, because,
as I've noted earlier, the constructor does not only do more than just
assigning the arguments to the fields, but it does nothing that has any effect
on the results of the other two former constructors.
The most consistent way of implementing such a design I could think of would be
to make a constructor that really _only_ assigns the fields, and move
everything else, _including_ the validation and reduction currently inside
{{BigFraction(BigInteger, BigInteger)}}, to static factory methods. But this
would create the problem I described in the first paragraph, so I don't think
it would be a good idea either.
> "BigFraction(double)" is unnecessary
> ------------------------------------
>
> Key: NUMBERS-123
> URL: https://issues.apache.org/jira/browse/NUMBERS-123
> Project: Commons Numbers
> Issue Type: Improvement
> Components: fraction
> Reporter: Gilles
> Assignee: Gilles
> Priority: Trivial
> Fix For: 1.0
>
> Attachments: NUMBERS-123__Javadoc.patch
>
> Time Spent: 0.5h
> Remaining Estimate: 0h
>
> Constructor {{BigFraction(double value)}} is only called from the
> {{from(double value)}} method.
> Actually, this constructor is misleading as it is indeed primarily a
> conversion from which appropriate {{numerator}} and {{denominator}} fields
> are computed; those could be set by
> the "direct" constructor {{BigFraction(BigInteger num, BigInteger den)}}.
> Moreover, the private field {{ZERO}} goes through this conversion code
> whereas it could constructed "directly", e.g. using {{of(0)}}. Similarly for
> field {{ONE}}.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)