Related
I am new to UML design, and I would like to know how to get started in developing Class Diagrams for a website, like facebook or twitter. The backend for a class diagram is simple, but for frontend, I have no idea what to do. I know I need classname, attributes, and operations. But I don't know how this would apply to the UI portion of a website.
I have searched the web, and there is not a lot of material on web page class diagrams. I might have not searched extensively, but I am hoping that someone could help me learn this.
Well, your question is a bit too broad. Alas I'll try a short answer.
As you stated you got the idea behind class diagrams. So you probably have some kind of domain model. A set of classes on client and server side. Now the best approach is to begin with use cases where you describe the behavior of your system and the system goals. Now you create collaborations that realize these use cases. Inside those collaborations you place instances of those classes (in sequence diagrams) from your system domain that take part in the specific use case. Here you start sending messages (using methods of classes) to communicate between the single instances. Add methods/calls as you need to complete the specific design. When done you can create test/start coding the classes.
Of course the above is by fa more complex in practice (you have to deal with different stakeholders) and you find a couple of dependent loops in the process. As said: elaboration of these aspects would us take too far.
Standard way of working on new API (library, class, whatever) usually looks like this:
you think about what methods would API user need
you implement API that you suspect user will need
So basically you trying to guess what your API should look like. It very often leads to over engineering stuff, huge APIs that you think user will need and it is very possible that great part of your code won't be used at all.
Some time ago, maybe few years even, I read some article that promoted writing client code first. I don't remember where I found it but author pointed out several advantages like better understanding how API will be used, what it should provide and what is basically obsolete. I think idea was that it goes along with SCRUM methodology and user stories but on implementation level.
Just out of curiosity for my latest private project I started not with actual API (some kind of toolkit library) but with client code that would use this API. Of course my code is all in red because classes, methods and properties does not exist and I can forget about help from intellisense but what I noticed is that after few days of coding my application "has" all basic functionalities and my library API "is" a lot smaller than I imagined when starting a project.
I don't say that if somebody took my library and started using it it wouldn't lack some features but I think it helped me to realize that my idea of this API was somewhat flawed because I usually try to cover all bases and provide methods "just in case". And sometimes it bites me badly because I made some stupid mistake in basic functions being more focused on code that somebody maybe would need.
So what I would like to ask you do you ever tried this approach when needed to create a new API and did it helped you? Is it some recognized technique that has a name?
So basically you're trying to guess what your API should look like.
And that's the biggest problem with designing anything this way: there should be no (well, minimal) guesswork in software design. Designing an API based on assumptions rather than actual information is dangerous, for several reasons:
It's directly counter to the principle of YAGNI: in order to get anything done, you have to assume what the user is going to need, with no information to back up those assumptions.
When you're done, and you finally get around to using your API, you'll invariably find that it sucks to use (poor user experience), because you weren't thinking about how the library is used (UX), you were thinking about what the library must do (features).
An API, by definition, is an interface for users (i.e., developers). Designing as anything else just makes for a bad design, without fail.
Writing sample code is like designing a GUI before writing the backend: a Good Thing. It forces you to think about user experience and practical effects of design decisions without getting bogged down in useless theorising and assumption.
And contrary to Gabriel's answer, this is not bottom-up design: it's top-down. Rather than design the concrete backend of your library and then force an abstract interface on top of it, you first design the interface and then worry about the implementation.
Generally speaking, the idea of designing the concrete first and abstracting from that afterwards is called bottom-up design. Test Driven Development uses similar principle to what you describe to support better design. Firstly you write a test, which is an use of code you are going to write afterwards. It is important to proceed stepwise, because you have to proove the API is implementable. IMportant part of each part is refactoring - this allows you design more concise API and reuse parts of your code.
How is a class diagram actually any different to just looking at the class definition with all the functions collapsed? I've been asked to write some and realized that this is all just .. read the source .. it has comments. What's the point of a class diagram, how is it different to even minorly commented definitions, and what makes a good class diagram better than others?
Edit: Yes, the source already exists, and did so long before the class diagrams.
Another edit: People have been talking about visual vs textual tastes. That's not the definition of class diagram I was given. It's still purely textual. The sample class diagram is a bunch of text, that resembles the source code with the function definitions cut. That's the reason that I asked. If it was a genuine diagram, I could understand.
If you have one or two classes, that does not make a diference.
If you have a complex object model, things change.
And, at least for me, is easy to look first at a diagram in order to look for what I want in stead of looking at a bunch of source files.
Also seeing the classes on a picture and their relations helps to understant the ideas of the project.
I'd rather have source. Given that, I can always reverse engineer it.
You have to ask what UML is for: it's just a communication device, a way to get your ideas across to other developers. If UML is helping, great. If it becomes another burden to maintain, prefer working code with good unit tests.
A good class diagram clearly shows each classes responsibilies and associations - at an appropriate level of abstraction.
Class diagrams are useful because they allow you to design at a higher level of granularity. Operations drawn on a white board are easier to change than source code. It also clearly shows associations through lines, rather than leafing through code.
They're helpful in that they are a segue from conceptual ideas to source code.
They let you say more with less.
If the source already exists, I guess it's the old adage, "A picture tells a thousand words".
For someone not familiar with the source, a diagram may help them to grok the overall design quicker then reading the source, no matter how well documented. Some people are more visual than others. Personally, I'd rather have the source.
Like many things, it's probably a matter of taste.
Edit:
I thought the definition of a diagram was that it is visual. However, if it's just a bunch of text, then the only point I can see is that it provides an overview of intent without the unnecessary implementation details.
The difference between looking at a diagram and the source is that you don't need to process as much data when looking at the diagram (a picture) than when reading the source (says thousand words).
In my experience I've found class diagrams to be very useful when I'm not familiar with the architecture of the software. But class diagrams don't replace the need for source code and proper documentation, they're just a communication and productivity tool that complement the methods I mentioned before. Their intent is to understand the software architecture. not to replace other documentations. How useful a class diagram is depends on its quality and the complexity of it and the source code.
Don't put too much detail into the diagrams. It makes them confusing. You'll want them to communicate relationships, not API and a list of methods.
They also help to see when and where to refactor code. Use class diagrams along with proper documentation and you'll be all set.
I'm not sure quite what definition you've been given for a Class Diagram - it sounds almost as though the example you've been shown has just one class on it. If so, I can understand why you think it's a bit ridiculous.
Class Diagrams are a way to show the relationships between classes - a good one can provide a lot of information about how your system works in one diagram that rewards careful study. It allows a developer unfamiliar with a subsystem to come up to speed quickly without getting mired in the implementation details.
Here's one simple one I found with a quick Google:
http://netbeans.org/images_www/articles/uml-class-diagram/Completed-Class-Diagram.gif
Some tools (Microsoft's Visual Studio is one) contain tools that allow you to draw a class diagram once and have it automatically kept up to date ("in synch") with the code. Very useful.
EDIT:
Wow, the initial response to this question was quite negative. I think I might have triggered some pretty strong emotions by using the word "best"; it seems like a few people latched onto that word and decided to dismiss my question right away.
Obviously, there are many, many situations in which no single approach is "best", or at least, what ends up being the best solution to one problem will often not be the best solution for other, even similar, problems. I get that. But now let me try to elaborate on the reasoning behind what I'm actually asking.
I tend to find it easiest to explain myself using analogies, so here goes. In my current job I work almost exclusively in .NET. .NET has a lot of functionality built into the framework. A prime example is the System.Collections.Generic namespace, which has a bunch of collection classes that (almost) no .NET developer in his/her right mind would bother re-developing from scratch, because very good implementations are already there. If I am working on a problem that requires a doubly linked list, I'm not going to decide, "Okay, time to write a doubly linked list class"; I'm just going to use the LinkedList<T> that's already there, or, at most, extend it or wrap it with my own class that adds some extra functionality.
Am I saying the "best" version of a doubly linked list is LinkedList<T> from .NET? Of course not. That would be absurd. But I highly doubt .NET's implementation of LinkedList<T> is drastically different from most other established libraries' implementations of collections that are intended to serve the same purpose (that of a doubly linked list). On the other hand, I am relatively confident that if I were to write my own implementation from scratch, there'd be a considerable number of issues with it, in terms of robustness, performance, flexibility, etc. for one simple reason: not that I'm stupid, or lazy, or don't care about good code--simply that I'm one person, and I'm not an expert on linked lists, and I haven't thought of everything that needs to be taken into consideration when designing one.
But I happen to be a developer who does take an interest in how things are implemented internally. And so it would be nice if I could check out a page where some variant of a well thought-out design for a linked list--or for any fairly established concept for which robust, efficient implementations have been written--were available to view. (By the way, yes I am aware that the source code for .NET's LinkedList<T> is available. I'm just using that as an example; really I am talking about all problems with solutions for which good, working implementations exist.)
Now, I talked about this being something that is open; let me elaborate on that. I am not talking about sites like SourceForge.net, or CodePlex, or Google Code. These are all sites for hosting projects, i.e., applications or libraries tailored for some specific industry or field or otherwise categorizable purpose. What I'm talking about is something like this:
http://en.wikibooks.org/wiki/Category:Algorithms_and_data_structures
Maybe I should have just provided that link in the first place, as it probably illustrates what I'm getting at better than anything I've written so far. But I think the main point that differentiates what I'm asking about from any other site I've seen is that I was specifically wondering if there could be some way to work on a new problem--so, something for which there aren't necessarily any well-known, established implementations, again as in my linked list example--collaboratively, in a wiki-esque fashion, but not tied to any specific open-source project.
So, as a conclusion of sorts, I was kind of envisioning a situation like the following: I find myself faced with a new problem. Maybe it isn't common enough to be something that is addressed in a framework like .NET. But it's common enough that some developers here and there are independently working on it. If a website exists like what I'm imagining, maybe at some point one of those developers working on the problem could post an idea on that website, and over time others might discover it and suggest improvements/modifications, and given enough time and participation, a pretty darn good implementation might result from all this collaboration. And from there, eventually, something like this implementation might be considered fairly "standard", just like a linked list implementation, or a quicksort implementation, or, I don't know, some well-known pseudo-random number generator.
Does this make any more sense to anyone now? I feel quite confident that what I'm talking about is not absurd, but hey, if that's what people think, then maybe it is.
Open source projects are very popular. Some of these are libraries suited for specific purposes, the best of which include some very well-written code.
However, if you're interested in contributing to an open source project, finding a project that is well-suited to your skills can be quite a task. At the same time, if you're interesting in using an open source project in your own work, finding a project that is well-suited to your needs can also be difficult, especially when, for example, open-source library X has a lot of functionality you could use, as does library Y, and these two libraries' capabilities overlap so that integrating both into your code could be messy.
We've all seen questions, here on Stack Overflow and elsewhere on the web, posted by one developer: "How would I implement this idea?" and answered by others, often accompanied by a plethora of example code. Sometimes these answers link to an open source project/library that provides functionality similar to what the poster is asking about.
My question is: are there any well-known websites or other sources that are open in nature and provide "best-known implementations" for common (or even not-so-common) programming problems, but not associated with any particular open source project?
As a generic example, suppose I have a need for some algorithm that does X. I post a question on SO or some other site requesting ideas, asking for suggestions on how best to implement it. One person points me to project P1, which contains some code that performs something very similar to this algorithm. Another person points me to project P2. Someone else writes some sample code and says, "maybe you could do it like this."
It seems to me, if there are all these different versions of this idea floating around out in the world, it would make sense for there to be a site, somewhat in the vein of Wikipedia, where a quasi-"official" implementation ("official" is not the right word; I'm just having trouble thinking of a better one right now) could be published and modified as improvements are developed/discovered.
I feel like I have stumbled across a few different sites like this in the past, but I'm interested to know if anyone else has found any resources like what I'm describing.
The very idea is absurd. It means that there's one, single opinion on "best-known implementations" with no changes based on other people having better ideas.
It implies a that best practices are static and can be accumulated into a single repository.
If they could be collected, then Google would have them and would simply charge for access.
Interestingly, they don't have all the best practices. Interestingly, they have to expend mountains of computing power looking for more information. Then people (like you) have to read and think and judge and decide.
The read-think-judge-decide is really hard to eliminate. Unless, of course, you want someone to think for you. In which case, there are many companies who have a single solution that requires less thinking. Call Microsoft or Oracle or IBM. They have solutions that are all in one place, unified best practices, no reading, no thinking, no judging, no deciding required.
Open -- by definition -- means it's impossible to have a single authoritative source.
Here is something, maybe not the best implementations. But a book called Design Patterns contains what is considered by many programmers some of the best patterns to follow!
I seem to use bland words such as node, property, children (etc) too often, and I fear that someone else would have difficulty understanding my code simply because the parts' names are vague, common words.
How do you find creative names for classes and components to make them more memorable?
I am particularly having trouble with generic tools which have no real description except their rather generic functional purpose. I would like to know if others have found creative ways to name things rather than simply naming them by their utility, such as AnonymousFunctionWrapperCallerExecutorFactory.
It's hard to answer. I find them just because they seem to 'fit'.
What I do know, however, is that I find it basically impossible to move on writing code unless something is named correctly, and it 'feels' good. If it isn't named right, I find it hard to use, and the code is generally confusing.
I'm not too concerned about something being 'memorable', only 'accurate'.
I have been known to sit around thinking out loud about what to name something. Take your time, and make sure you are really happy with the name. don't be afraid of using common/simple words.
I don't really have an answer, but three things for you to think about.
The late Phil Karlton famously said: "There are only two hard problems in computer science. Cache Invalidation and Naming Things." So, the fact that you are having trouble coming up with good names is entirely normal and even expected.
OTOH, having trouble naming things can also be a sign of bad design. (And yes, I am perfectly aware, that #1 and #2 contradict each other. Or maybe one should think of it more like balancing each other.) E.g., if a thing has too many responsibilities, it is pretty much impossible to come up with a good name. (Witness all the "Service", "Util", "Model" and "Manager" classes in bad OO designs. Here's an example Google Code Search for "ManagerFactoryFactory".)
Also, your names should map to the domain jargon used by subject matter experts. If you can't find a subject matter expert, that's a sign that you are currently worrying about code that you're not supposed to worry about. (Basically, code that implements your core business domain should be implemented and designed well, code in ancillary domains should be implemented and designed so-so, and all other code should not be implemented or designed at all, but bought from a vendor, where what you are buying is their core business domain. [Please interpret "buy" and "vendor" liberally. Community-developed Free Software is just fine.])
Regarding #3 above, you mentioned in another comment that you are currently working on implementing a tree data structure. Unless your company is in the business of selling tree data structures, that is not a part of your core domain. And the reason that you have trouble finding good names could be that you are working outside your core domain. Now, "selling tree data structures" may sound stupid, but there are actually companies that do that. For example, the BCL team inside Microsoft's developer division: they actually sell (well, for certain definitions of "sell", anyway) the .NET framework's Base Class Libraries, which include, among others, tree data structures. But note that for example Microsoft's C++ compiler team actually (literally) buys their STL from a third-party vendor – they figure that their core domain is writing compilers, and they leave the writing of libraries to a company who considers writing STLs their core domain. (And indeed, AFAIK, that company does nothing but write and sell STL implementations. That's their sole product.)
If, however, selling tree data structures is your core domain, then the names you listed are just fine. They are the names that subject matter experts (programmers, in this case) use when talking about the domain of tree data structures.
Using 'metaphors' is a common theme in agile (and pattern) literature.
'Children' (in your question) is an example of a metaphor that is extensively used and for good reasons.
So, I'd encourage the use of metaphors, provided they are applicable and not a stretch of the imagination.
Metaphors are everywhere in computing. From files to bugs to pointers to streams... you can't avoid them.
I believe that for the purpose of standardization and communication, it's good to use a common vocab, like in the same case for design patterns. I have a problem with a programmer who keeps 'inventing' his own terms and I have trouble understanding him. (He kept using the term 'events orchestrating' instead of 'scripting' or 'FCFS process'. Kudos for creativity though!)
Those common vocab describe stuff we are used to. A node is a point, somewhere in a graph, in a tree, or what-not. One way is to be specific to the domain. If we are doing a mapping problem, instead of 'node', we can use 'location'. That helps in a sense, at least for me. So I find there is a need to balance being able to communicate with other programmers, and at the same time keeping the descriptor specific enough to help me remember what it does.
I think node, children, and property are great names. I can already guess the following about your classes, just by their "bland" names:
Node - this class is part of a graph of objects
children - this variable holds a list of nodes belonging to the containing node.
I don't think "node" is either vague or common, and if you're coding a generic data structure, it's probably ok to have generic names! (With that being said, if you are coding up a tree, you could use something like TreeNode to emphasize that the node is part of a tree.) One way you can make the life of developers who will use your API easier is to follow the naming conventions of your platform's built in libraries. If everyone calls a node a node, and an iterator an iterator, it makes life easy.
Names that reflect the purpose of the class, method or property are more memorable than creative ones. Modern IDEs make it easier to use longer names so feel fee to be descriptive. Getting creative won't help as much as getting accurate.
I recommend to pick nouns from a specific application domain. E.g. if you are putting cars in a tree, call the node class Car - the fact that it is also a node should be apparent from the API. Also, don't try to be too generic in your implementation - don't put all attributes of the car into a hashtable named properties, but create separate attributes for make, color, etc.
A lot of languages and coding styles like to use all sorts of descriptive prefixes. In PHP there are no clear types, so this may help greatly. Instead of doing
$isAvailable = true;
try
$bool_isAvailable = true;
It is admittedly a pain, but usually well worth the time.
I also like to use long names to describe things. It may seem strange, but is usually easier to remember, especially when I go back to refactor my code
$leftNode->properties < $leftTreeNode->arrayOfNodeProperties;
And if all else fails. Why not fall back on a solid star wars themed program.
$luke->lightsaber($darth[$ewoks]);
And lastly, in college I named my classes after my professor, and then my class methods all the things I wanted to do to that jerk.
$Kube->canEat($myShorts, $withKetchup);