Path: csiph.com!1.us.feeder.erje.net!feeder.erje.net!1.eu.feeder.erje.net!news.unit0.net!newsreader4.netcologne.de!news.netcologne.de!.POSTED.xdsl-87-79-255-186.netcologne.de!not-for-mail From: Patrick Roemer Newsgroups: comp.lang.java.programmer Subject: Re: double == double Date: Mon, 17 Oct 2016 18:58:09 +0200 Organization: news.netcologne.de Distribution: world Message-ID: References: <8737k0qd38.fsf@golem.phantasia.org> <87zim5es30.fsf@golem.phantasia.org> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit Injection-Date: Mon, 17 Oct 2016 16:58:09 +0000 (UTC) Injection-Info: newsreader4.netcologne.de; posting-host="xdsl-87-79-255-186.netcologne.de:87.79.255.186"; logging-data="19101"; mail-complaints-to="abuse@netcologne.de" User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.24) Gecko/20100411 Thunderbird/2.0.0.24 Mnenhy/0.7.6.0 In-Reply-To: Xref: csiph.com comp.lang.java.programmer:35801 Responding to Arne Vajhøj: > On 10/16/2016 5:19 PM, 4ndre4 wrote: >> On 16/10/2016 19:14, Arne Vajhøj wrote: >> >> [...] >>> But that code is not using String as version >> >> Erm... how about this? :) I don't see how this is less OO-ish than the >> previous one, but hey... okay!...: >> >> List versions = new ArrayList(); >> >> versions.add("1.9.0-123"); >> versions.add("1.10.0-123"); >> versions.add("1.7.0-123"); >> versions.add("1.7.0-123"); >> versions.add("1.7.0-10"); >> versions.add("1.7.0-9"); >> >> Collections.sort(versions, new VersionComparator()); >> >> ... >> >> static class VersionComparator implements Comparator { > >> public int compare(String version1, String version2) { >> try { >> ParsedVersion pv1 = parse(version1); >> ParsedVersion pv2 = parse(version2); >> if (pv1.equals(pv2)) return 0; >> if (pv1.lessThan(pv2)) return -1; >> return 1; >> } catch (InvalidVersionException e) { >> throw new IllegalArgumentException(e); >> } >> } > > Having data and methods operating on the data separate is > very non-OO'ish in my book. I don't think this describes the actual problem well. There may be perfectly good, OO-compatible reasons to separate comparison logic from the domain class - after all, that's why Comparator exists. For example, there may be occasions when one wants to compare only based on the major (major + minor,...) version parts. But this code defies a more general programming principle: Describe your concepts as dedicated types and define operations for those types. Passing an opaque string around to be interpreted as a version only "when needed" feels fishy to me in any paradigm. With this approach, one has to rely on variable names and comments to know what the string is supposed to represent. It is inefficient, because one is bound to re-parse on every comparison. And there's no easy way of knowing whether a given variable holds a valid version number or whether one has to be prepared for an exception upon comparison. With a dedicated Version type, you parse once at whatever boundary the string enters the system, and from then on you have a guaranteed valid version with a "speaking" type that can be compared efficiently and that can easily be extended with other version-specific functionality in future, erm, versions. Best regards, Patrick