thanks Oliver, I know about is-a and has-a but in this case I just want do what I can do in 2 seconds with MFC just setting a property. I've already spent so much time, so the faster solution is the best solution for a so simple problem. going for validator inheritance.
pm 2014-08-08 20:14 GMT+02:00 Till Oliver Knoll <till.oliver.kn...@gmail.com>: > Am 08.08.14 18:08, schrieb pmqt71: > > ... > > @Oliver: > > yes my problem is that QLineEdit can have only 1 validator. I think > > inherithance should be easier than implementin a ChainValidator, am I > right? > > We could now fill pages of discussions about "Inheritance being evil", > "is-a" vs "has-a" vs "uses-a" relations etc., and we'd end up having at > least 10 times more opinions than possible ways of implementing the > solution ;) > > (Just start by asking Google with "Inheritance is Evil" - and you get > the idea ;)) > > Here is just a starter link: > > http://en.wikipedia.org/wiki/Composition_over_inheritance > > > Personally I try to question inheritance as much as possible. The > classic question is "Is a Square also a Rectangle"? > > The best practical explanation - and design question you should ask > yourself whenever you have inheritance in mind - I ever read is: would > an instance of a derived class pass all (possible and sensible) unit > tests of a base class? > > Let's continue with the "Shall I derive my Square class from the > Rectangle class?"-example (which is really a classic, but as such > probably also of "academic value") and let us further assume there was a > unit test which would verify the "area" method. > > So the test would look something like: > > int width = 3; > int height = 5; > Rectangle rect; > > // setup > rect->setWidth(width); > rect->setHeight(height); > > // exercise > int area = rect.area(); > > // verify > assert(area, width * height); > > > Now if you ran the same test, but with an instance of Square, that test > would fail! Why? Because our expectation is that whenever you modify > either width or height, the implementation of a Square would implicitly > set the height or width respective to the same value (otherwise the > instance would not be a square!). > > So after setting the height to 5, the width in above example would also > become 5 and the area would be 25 != 15. Fail. > > > Now would e.g. a UPPERCaseValidator inherited from a > LettersOnlyValidator also falsify unit tests in the same way? Most likely. > > > > There is another reason why particularly in this example I would > definitively opt for the "ChainValidator" (-> composition): it is way > more flexible! > > Let's assume you had 3 validators A, B and C and an additional > "UPPERCaseValidator" (4 classes in total). If you wanted to have for > each A, B, C Validator a combination, you'd have to come up with another > 3 classes (deriving each time from A, B and C respective)! So that would > be 7 classes in total to maintain (and if you need to fix something in > your UPPERCaseValidator implementation, you'd need to fix it 3 times in > the worst case - you could share parts of the implementation, but > still...). > > > With a composition pattern you'd only need one extra class - a > "ChainValidator" - and you could combine either A, B or C with your > UPPERCaseValidator. Only one additional class, total 5 classes. > > "Well, 5 or 7 classes", what's the big deal anyway! > > Well, here is the deal: just add one more validator D, and your number > of classes grows linearily (and so are the number of implementations to > maintain): not only do you have another class D, but also a new derived > class from D - total 9 classes! For every "base validator" class that > you'd add you would have to implement yet another derived class > (assuming off course that this would make sense to have an > UPPERCaseValidator also validate the output of all A, B, C and D classes). > > > But here's an even bigger deal: Let's assume your boss now tells you > that you need to validate A, B - AND C! Or any combination thereof > (boss: "Oh and yes, off course, don't forget about our new shiny > UPPERCaseValidator class, add that to the mix, too! And the new > validator D that we just purchased yesterday..."). > > So would you want to come up with classes such as ABCUpperCaseValidator, > CBAUpperCaseValidator, AUpperCaseValidator, BUpperCaseValidator, > CUpperCaseValidator, ... (the names reflect the "inheritance chain")? > Hopefully not! A combinatorial explosion of possible inheritance > permutations! > > > With the "ChainValidator" however you would simply assemble the > validators like so (pseudo-syntax - you get the idea): > > AValidator a; > BValidator b; > CValidator c; > UPPERCaseValidator d; > ChainValidator ca; > > > // validates a and d > ca.add(a); > ca.add(d); > state = ca.validate(theString, pos); > > ca.clear(); > > // validats a, c and d > ca.add(a); > ca.add(c); > ca.add(d); > ca.validate(theOtherString, pos); > > > No need to come up with new classes! And just one single > UPPERCaseValidator implementation! > > (Again, whether the above actually works when it comes to validation, I > don't know - clearly there would be combinations which would not make > sense at all, but in the worst case you'd probably just get an Invalid > state with /any/ input). > > > > Now all that said: the above might be complete "over-engineering" in > your particular case! If you have 2 or 3 very specific cases to validate > "in just that particular dialog" and "I will never ever have the need to > ever re-use those inhertited validation classes anywhere - I swear!" > then go for inheritance - it is not "per se evil" ;) Just know the > consequences. > > > Cheers, Oliver > > _______________________________________________ > Interest mailing list > Interest@qt-project.org > http://lists.qt-project.org/mailman/listinfo/interest >
_______________________________________________ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest