16 ms·
How to design a class
- asveikau 13y agoI think this seems a little too existential. What is more important, that you classified the right nouns and verbs in your Paws and Dogs, or that your code works? In my view OOP is all about sane interfaces between components. In your internal code however, you should feel free to let your implementation details and data structures drive the flow, and not con yourself into writing OO spaghetti, that type of code written by inexperienced types who "heard somewhere to use classes" and can only think in classes, and the abstraction serves to obfuscate rather than clarify.
- AlisdairSH 13y agoAfter years of software design, I can say with a high level of confidence that classifying the nouns and verbs properly is a prerequisite to quality OO code (from both a functional AND longevity standpoint). If you fail to do that up-front analysis, you may end up with functional code. But, the likelihood that it is readable, maintainable, extensible, etc is much lower. This isn't to say that all good code is OO. Only that writing good OO code requires you to define the objects andt their interactions well.
- CraigJPerry 13y agoHere framing the problem around a Walk class makes for a more elegant implementation but the proscribed steps will never get you there.
- blahbl4hblahtoo 13y agoI really enjoyed this...the upvoted answer was really helpful. I'm going to use it tonight when I get home and can work on a personal project.
- odonnellryan 13y agoI liked this a lot, but do we think all those steps are needed? I feel like it can definitely be simplified, and that this is even scary for people new to Python and OOP.
- markkanof 13y agoI suspect that you have some amount of experience that allows you to just do many of these things intuitively (possibly in your head without writing them down). For a beginner, I think it can be helpful to have a detailed procedure to follow that takes them from start to finish. That way they can focus mental energy on the problem at hand while not having to worry that they may be working through the problem using a method that is inefficient or that may never get results.
- hootener 13y agoI really don't think it's the physical process, but the kind of detailed analysis of your problem and the requisite thinking to form a solution that the described process requires. Good OO programmers do some internal version of this process every time they design a class. For those that have been at it awhile, this process is probably so internalized they hardly even notice it. The OOP equivalent of muscle memory. For example, the value in "underline and review the nouns" isn't underlining and reviewing the nouns, it's a physical manifestation of an important step in the OO development process. Namely, helping to identify requirements. Have I ever gone through such a tedious process when designing a class? Of course not, but the steps outlined in the answerer's post take place in some form internally every time I need to design a new class.
- talles 13y agoSurprisingly not marked as 'too abroad' or something like that on SO... I guess on 2010 people were more light on that
- maaaats 13y agoWhy does every thread featuring SO contain this knee-jerk response? If anything, HN is the "bad" place with its constant nagging.
- saraid216 13y agoHi, my username is saraid216 and it has been 123 days since I quit Facebook. ...oh, wrong thread.
- talles 13y agoCare to cite one of those "knee-jerk" responses that you are talking about? If someone is nagging here I assure it's not me. Just found curious that they weren't rigid as they normally are nowaydays to these question. If this one was an exception or they got more harsh over time is what I wondered. This is the first reply to me that I recall here on Hacker News that someone over interprets something I said (in a bad way). I don't think so but anyway if I sounded like I was complaining I apologize, that is not the case (actually is the quite opposite, I love those more open questions).
- xtr 13y agoThanks, I also found this very beneficial.
- rayiner 13y agoObject oriented programming is awful, and this answer describes why. It shifts focus from algorithms to objects. As a result, you get these over-designed programs with lots of objects that have lots of methods, and the algorithm gets totally obscured. See: http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom....
- debaserab2 13y agoI hear this perspective a lot on HN. If OO programming is awful, do you have any examples of what you consider to be good code?
- SwellJoe 13y agoThere's cargo culting on both sides of the question. Because someone heard pg say he's not overly fond of overly OO code (which he has said in the arc design document), or some other well-known thought leader on programming (like Yegge), they then form a particular dislike of all OO code and even the idea of OO, itself. It's not rational or very fully formed for most of the folks who hate OO. Likewise, there are folks coming from (maybe?) a Java or C++ background, who feel that strict OO is the only sane way to approach designing a program. I'm not going to try to give examples of good or bad code in either category...but, will point out that Haskell is not an OO language (in the Grady Booch sense of OO, though you can encapsulate methods in data because it has first class functions), but there's an awful lot of beautiful and correct Haskell code out there. Likewise many other functional, Lisp, and ML-derived languages. OO design can obscure meaning, but there's no reason to get reactionary about it. It's one useful tool; it certainly works great for UIs and some types of API.
- deleted 13y ago[deleted]
- fatjohn 13y agoYou're right, except that Java and C++ don't have much to do with strict OO.
- ExpiredLink 13y agoActually, only #1 and #2, "simple statements about what these objects will be doing", are relevant. The 'nouns' points are misleading at best. OO is all about behavior ('services'), not about data. A class doesn't encapsulate data, it encapsulates state. That's a big difference that many OO aficionados don't realize. Another source of confusion is that in some OO languages 'everything' has to be a class. A Java class in many cases isn't a class in terms of OO. Java Beans e.g. certainly are not OO classes.
- deleted 13y ago[deleted]
- azov 13y agoLet's try this advice. Say, we're solving Hanoi Towers [1]. So, we're going to have rods, and disks, and rods are going to have the number of disks on them, and disks are going to have size, and probably a reference to the disk underneath, and a reference to the disk on top, and maybe also weight and color... and by the end of the day instead of a 10-line snippet [2] we're going to have Enterprise Java Beans. No, it doesn't mean that OOP is awful - it just means that this particular way of modeling a problem is a recipe for over-engineering. Start with the simplest thing that works. That thing will probably be just a function. Grow it from there. If it gets too big, split it. If you find that you pass the same 12 parameters to a bunch of functions - factor out a class. If you do the same thing in a bunch of classes - abstract it out. Keep it DRY [3]. Keep it SOLID [4]. Rinse and repeat. This way you end up with a useful class hierarchy - and OOP won't be awful. [1] http://en.wikipedia.org/wiki/Tower_of_Hanoi http://en.wikipedia.org/wiki/Tower_of_Hanoi [2] http://rosettacode.org/wiki/Towers_of_Hanoi http://rosettacode.org/wiki/Towers_of_Hanoi [3] http://en.wikipedia.org/wiki/Don't_repeat_yourself http://en.wikipedia.org/wiki/Don't_repeat_yourself [4] http://en.wikipedia.org/wiki/SOLID_(object-oriented_design) http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
- aidos 13y agoI think that's a little too black and white back the other way. Don't get me wrong, I live in python, I create classes on the odd occasion I need them and not before it's definitely required. That said, there's nothing wrong with sitting down and modelling the problem you're trying to solve on paper to try to understand what's involved. You don't need to implement it that way. Whatever you do, stop and take a moment to think it through.
- chaosphere2112 13y agoThe thing that I keep finding myself wanting in Python is a more structured way to refer to data; fortunately, that's what namedtuple[1] is for. >>> DataType = namedtuple("DataType", ["field1", "field2"]) >>> datum = DataType(1, "a") >>> datum DataType(field1=1, field2='a') >>> datum.field1 1 >>> datum.field2 2 Keeps my code a bit more sensible than constantly indexing into tuples, imo. [1]: http://docs.python.org/2/library/collections.html#collections.namedtuple http://docs.python.org/2/library/collections.html#collection...
- jamesli 13y agoIt is utterly ill-advised. Software design is about abstraction, to make code modular, flexible, and extensible. It doesn't matter it is OOP or FP. Both approaches have their own advantages and limitations. The dogmatic answer is misleading. It might be ok to introduce OOP to new programmers, to open a door for programmers who are only familiar with procedural programming. For any experienced programmers, if they don't believe in this dogma, I have to say this is not a right career for them.
- spion 13y ago1. First, write some use case scenarios/specs in order to get a better understanding of the problem (for libraries this is README.md, for user-facing programs its the user's problem and the solution's workflow) 2. Write the code the way you would ideally want it to work, top-down. Imagine that you're in fantasy land. Don't worry about it being wrong or impossible to do that way. That will be corrected later. Use classes to express blueprints for tiny worker machines that work on data, not the data itself. Use classes to simulate entities. A user is not the user's personal information - thats a data structure. A user class makes sense in a testing framework where you want to simulate the process of a user visiting a website. A button is a worker machine that can detect a set of inputs and call attached functions. A list is a worker machine that can keep items and update the screen based on its scroll position. A stream is a worker that can be customized to process incomming data packets in a certain way, and its output can be connected to another stream. Think of classes as tiny single-purpose computers or simulators. 3. Express details about the desired outputs of that top-down code as tests. 4. This is a good time to write all the data structures to represent your data. You can use relational modeling here even if you're not using a relational database (or any kind of database), but you can also use pointers/references instead of foreign keys. Model the data structures for all data (including computed data), not just input or stored data. You can also do this before step 2. but in that case you will be tempted to write your code to operate directly on the lowest level data structures, instead of making it look clean and simple. 5. Try to make the tests pass. 6. If its impossible to implement or you realize its not a good idea to implement it that way, tweak the test a bit then change your code and data structures as you get a better understanding of the problem. 7. Once you're satisfied with the test, you can stop. 8. If the future of the program requires you to adapt it, keep working like that over the existing code. The tests give you some reasonable assurance that it still solves the old variant of the problem, while new tests will ensure that the code sanely solves newer problems too.
- zwieback 13y agoIt's interesting to note that the question was "how to design a class", which to me sounds like a question about static structure, e.g. what data members and methods will the class have. Most of the discussion on this and the SO page mixes in OOD, OOP with the original question and then throws in some inappropriate OO vs. FP tangents. It's important to remember that there's a lot of, for lack of a better word, "class-oriented design" which typically tries to model the static structure of the physical world or some artefacts of the programming environment. In a completely separate world there's what I would call OO design and programming which is more concerned about the interaction of actual objects aka. instances of classes. Coming from the statically typed world the distinction is often unclear but for the original Smalltalkers and other OO purists object orientation was never about classes.
- jofer 13y agoAnd another one of Ivo's set of dog paw questions randomly become popular! The guy has a knack for asking good questions and getting good answers.
- ivoflipse 13y agoThanks :-) Your answers on some of those other questions really helped me get into this type of analysis. I'm even still working on my this dogs project (https://github.com/ivoflipse/Pawlabeling https://github.com/ivoflipse/Pawlabeling), the automatic labeling of the paws still needs a better solution!
- Jare 13y agoThis is almost word by word what I was taught about OOP in Introduction to Programming back in 89. We used Modula-2, but it was already easy to connect with the way we had been writing games in assembler. Later on, languages built for OOP like C++ or Java, with all the complexity and new features, shifted the focus of teaching programming from the problem domain (what I need my code to solve) to the language domain (what code I can write), and then Patterns arrived, and things quickly got hairy and over-engineered and big.
- ismarc 13y agoWhen I first used oop, or any object orientation, it was in the early days of the public internet. There wasn't nearly the resources available now, especially for a hobbyist. So when I learned the syntax (I believe it was early c++), I had nothing else to go on. I naturally leapt to using objects to describe and build new data types. It made me think about what data I needed, then how the data needed to be operated on. It wasn't until I started taking courses that I heard the noun approach... And it just seems completely backwards. It isn't about modeling your data, it's about the conceptual items you're working on. I still think oop is a good approach if you ignore all of the 'best practices' and instead use it to build custom data types that simplify your algorithms. It's part of what I really like about Erlang records (even though they're a bit annoying to use) and Scala in general. You can build custom data types without having to just compose lists and maps but you get a lot of the benefits from functional programming. I really don't understand why so much of the programming classes, tutorials, guides and common wisdom aren't 'data first' style design.
- djvu9 13y agoAt first sight I thought it is sarcasm...
- yetanotherphd 13y agoThe advice being given is more applicable to problems which have some real state inherent in the problem, e.g. network connections, UI state or databases. In numerical programming, state is less obvious because it depends on how you do the calculation. In numerical programming, I tend to use a functional style that makes use of objects. E.g. instead of y = f(params, x) I would write y = my_object.f(x) where my_object encapsulates params. This makes sense as the only function that needs to access params is f. On the other hand Python has no private members anyway so I would probably use the first way for Python anyway.