PhD Research On Software Design Principles?
cconnell writes "I am working on a PhD in software engineering at Tufts University. My interest are the general principles of good software design, and I am looking for links/references on this topic. The question is: What design/architecture qualities are shared by all good software? Good software means lacking in bugs, maintainable, modifiable, scalable, etc... Please don't tell me 'use object oriented methods' or 'try extreme programming.' These answers are too narrow, since there is good software written in COBOL, and by 1000-person teams for DoD projects. I am looking for general design principles. If it helps, I am trying to build on the ideas in this article from some years back."
The sell any one piece knows about the other pieces, the better off the system will be.
Badass Resumes
This is an excellent place to start:
http://www.cc2e.com/
AC
Personally I only do extreme, object oriented programming in COBOL, so I have nothing new to offer.
If brevity is the soul of wit, then how does one explain Twitter?
I mean what percentage of your PhD will be mine? Is it your PhD or our PhD. You want the degree, son? Earn it.
sed -e 's/Chuck Norris/Rajnikant/g' joke > fact
Good code avoids putting variables or functions unnecessarily in the global namespace. This means that the likelihood of name collisions is less likely so your code project is more likely to play nice with other code projects.
It's also good practice to try and make all of your code non-reentrant and threadsafe. As processors sprout an increasing number of cores, it is important to make sure your code can take advantage of the extra power.
It's also a good idea to COMMENT your code and DOCUMENT your processes. There's nothing worse than stumbling across something you wrote 10 years ago and having no idea how it works.
From what I can see, the real answer, process. Having a documented process that you follow to ensure that code is free of bugs, and that code is readable. How you accomplish those things isn't exactly important. For making sure code is readable and maintainable, you can have formalized code walkthroughs, or you could just have another coder read it over before it is accepted into the project. Ensuring that the software doesn't have any bugs is another issue. You should have a repeatable test environment, whether it be unit tests, or even just a list of actions peformed by an actual person, in order to check that everything is working correctly. Some approaches work better than others. But the real important thing in the end, is to have a defined process, and ensure that it is being followed.
Anthropic principle: We see the universe the way it is because if it were different we would not be here to see it.
Dear Mister PhD,
do your own damn homework.
Love,
the management
Read books by Ed Yourdon written in the 1970s.
Dave Barnes 9 breweries within walking distance of my house
http://www.htdp.org/
Use object oriented methods or, in the alternative, try extreme programming. Refactor whenever possible. Dissect and redistribute. Make sure the team is cohesive and factionalized. Compensate for all scalable factors on a frequent basis, using randomization approaches. Never, and this is not set in stone, allow the project to objectify to the point of opacity. This cannot be overemphasized: you can never add too much manpower to software tasks.
The article from earlier today seems to tell you how not to do it.
From my experience, I think the biggest thing is trust. The managers need to trust the developers to do what's right, and listen to the developers when they make suggestions on how to do it better. The developers need to trust that the managers won't get in their way, but will keep them on track and keep them insulated from distractions. Developers need to trust each other, that everyone's code works well etc, and trusts each other enough to ask for help when they need it. Once everyone trusts everyone else and can work well together, the project will be more successful.
Little secret: this goes for any project.
In my experience the single most important part to a software project is good requirement gathering and analysis. As for development, every program that i know uses some concept of divide and conquer. Breaking up a large problem in to a set of connected smaller problems simplifies writing good code. It's easier to write small bug-free modules then it is to write a large program all at once.
It would be interesting to find the cutoff point where a problem should be further divided and when it is discreet enough. Also, it would be interesting to know when a developer begins to introduce bugs or less optimized code. Like after x many lines or like y many hours.
It would be interesting to try and quantify code elegance. I forget who said it but there's a saying "code that looks good is good"
I came to the datacenter drunk with a fake ID, don't you want to be just like me?
I'm happy I don't have to tell him to use "Ask Slashdot".
Yahoo! Pipes are awesome. How awesome? http://pipes.yahoo.com/jesdynf/slashdot
Good software has:
Good software is written by good people. There is no general rules you can follow to automagically make your software good.
Sure some rules will tend to make your software a little bit better: KISS design principle, release early release often, unit tests, etc. But fundamentally it's all about people.
Then you might ask "what makes a good developer good". Well's that's not so easy to answer.
A software project is only as good its documentation. Look at successful open source projects -- many of these have excellent project documentation that tells you all about the architecture, structure, features, coding practices, standards implemented, data formats, data validation information and so forth.
WHat kills so many projects is a lack of good documentation -- if no one can figure out how to pick up the ball and code a feature or a bugfix or whatever, then the code will wither. This applies even to closed source projects -- one of the things that screwed Vista over, for instance is that much legacy code was in need of rewrite -- except there no one new what the code did anymore.
My blog
Most good software I've seen follows the KISS principle internally: Keep It Simple, Stupid. Pieces of it know what they're supposed to do and they do just that. They don't mix in functionality for several things. They don't have embedded knowledge of how they relate to the rest of the system. They've got clean, modular interfaces that let you test just that one part to make sure it's doing what it should and not doing what it shouldn't, without having to haul in large parts of the rest of the system. They either don't make assumptions about what the rest of the system will hand them or they've got those assumptions clearly documented in the interface and they test that their input conforms to those assumptions and produce a clear error if it doesn't. Eventually some pieces will have to embody the design and logic, understand how all the individual pieces fit together to make the system work, but that's their job: to orchestrate the work being done, not to actually do it.
Another indicator is that good software is designed with the certainty that it will change, that it will be extended and altered over time. Good software has that assumption built in. Bad software, by comparison, is often flagged by statements like "Don't worry, we're never going to change that." or "We don't need to worry about doing that.". Software designed not to change or be extended is either bad software or rapidly becomes bad software once it hits production.
And no, nothing particularly new there. It's been this way for about 50 years.
I strongly suggest you see if you can get a few weeks of academic internship with these people. Also know as 'Those who write the right stuff. They actually do know how to write software.
... whatever. And while people will start bickering that Apache or Blender code is oh so crappy in this or that area, rest asured that all projects of that kind, *incuding* the aforementioned *all* have core team members who are very well aware of the downsides of their software. And thus can help you out in your pursuit for details on professional software developement, because they also know the pitfalls.
Other places to look for: Linux Kernel team. Donald Knuths Tex/Latex.
Or, believe it or not, Blizzard Entertainment. They actually are the only entertainment software company I know of with a proven track record of extremely high quality software compared to others in the field.
But any core team of non-trivial low-level open source software technology will do actually. Python core team, PHP core team, your favourite Linux IO crew, Apache, OpenLaszlo, KDE, Haxe, Blender,
Bottom line: Join some tight crew of people that build stuff everybody uses or many people rely on to work. Hang with them for a month or two, then you'll have a better idea how exactly to approach your topic.
We suffer more in our imagination than in reality. - Seneca
I've been programming for almost 15 years and have spent alot of that time very gradually refining my own design principles. Here are my basics:
1. Modular designs. Modular code is generally more maintainable and more scalable.
2. Self-documenting code. If you read my code, you can understand whats going on just by the code. There are very few comments, because very few are needed.
3. Occam's Razor: The simplest solution is often the best/most correct solution. Over-complicating things often leads to maintainability issues later on.
I am currently working on a project that requires me to share code with several other people. None of them have needed much direction when picking up my code and re-using it because I've used sound design principles when writing it.
There really is no single answer that handles all situations. I use some more specific principles when doing different types of projects, depending on whether I'm doing Database design, web development, stand-alone applications or complex application systems.
System design is very subjective, every person seems to have a different way of doing things. One thing I always ask myself is this: Will I be able to work with this code 6 months from now? If the answer is no... then I have work to do to improve the design.
Thomas A. Knight
Author of The Time Weaver
The maturity of the management and its ability to insulate the coders from the noise from corporate is important to good code development.
Having an experienced architect is vital. Enforcement of the values of the team, especially with respect to interface specifications, is important.
Best regards.
I'm intrigued by this question, because I would assume that by the time you've reached this level (i.e. have a Master's in CS or something related) you would already have an idea as a starting point. Furthermore, I thought that the first part of any PhD-level research was an intensive Literature Review.
So, in other words, you should search LexisNexis, EBSCO, etc., and find some journal articles that talk about this. Read some books like Gang of Four or Mythical Man Month. Lastly, do your own data gathering. Find a bunch of Post-Mortems and start to put your own patterns together.
Oh, wait, all that would require work.
Seriously...I teach college-level courses and have multiple graduate degrees...and I'm continuously amazed at the quality that schools put out nowadays.
"You cannot find out which view is the right one by science in the ordinary sense." - C.S. Lewis on Intelligent Design
In some countries you have to submit a project in order to enroll into a doctorate programme, in others you become part of an ongoing project and your work will be a spinoff from that. Either way, I can't see how you are already working on your PhD and still making these sorts of questions.
2: Three seasons of Southpark.
That's The Simpsons for coding. Southpark is for debugging.
Man, you obviously have no idea. One of the critical skills is to choose the right tools for the right job.
We used to have a Bill of Rights. Now, with the rights gone, all we have left is the bill.
Sit down because what I'm about to say is very profound and could make you tear up.
I've heard that the key to good programs is.......GOOD PROGRAMMERS
Beer! It's what's for breakfast!
From one of the most respected developer/managers in the business, The Joel Test is a checklist that may help you with your ideas. http://www.joelonsoftware.com/articles/fog0000000043.html
Just be sure to add your Slashdot research to your .bib file:
@MISC{Slashdot:2008,
AUTHOR = "Level 70 Opinionated Geeks",
TITLE = "Musings on Software Design Principles",
HOWPUBLISHED = "Randomly Moderated Posts",
MONTH = "June",
YEAR = "2008",
NOTE = "Results from Ask Slashdot when I was too lethargic to look up CS articles online",
}
One of the most useful principles I've found for making "good" software is to design very clean, very powerful interfaces. Focusing on "modularity" often puts the focus in the wrong spot, namely on the center of the module. The point is that the details there *shouldn't matter* because you can abstract away all sorts of fiddly detailed functionality.
It is difficult to make clean and powerful interfaces, however. You really have to understand the nature of the problem you're trying to solve in order to pick the most natural groups of functionality. Very often, if you're trying to get something done in a reasonable amount of time and don't need to maintain the code for that long (though beware--you'll find yourself using, a decade later, programs that you thought you'd rewrite "next month"), it's better to code something quick and specific.
The cleanliness of an interface basically boils down to how little information you can pass to it, and how little information you need from it, in order for it to do what you want; and to what extent all information and data goes through explicitly defined interface elements (e.g. an interface in Java). (Here I'm drawing a distinction between data, e.g. the content of a character stream, and information, which is "hey, there's a character stream here, go work on it".)
The power of an interface basically boils down to how many different high-level operations can be constructed from mixing and matching components of the interface. For example, compositing operations tend to be powerful (e.g. take A, take B of the same type, perform some operation to produce C of the same type from A and B).
There are lots of other generally useful strategies, but I find this one of the most overlooked, especially by otherwise really talented coders (who can tend to make interfaces more complex because they are talented enough to work with something that complicated).
Why would a PhD student solicit for information on a social website? Shouldn't you be doing the research yourself??
Real engineers watch Futurama.... South Park and the Simpsons is for programmers and QA testings....
Muhahahah
To go even further on this path, abstraction and frameworks have improved my code quality and reduced my time to production.
Abstracting code as much as appropriate allows you to reuse a significant portion of your code base. And with designing a framework for your applications that utilize that abstracted functionality to allow for a modular design of the actual business logic will greatly improve almost all projects.
The business layer should have no idea what the database is or how it works.
The presentation layer should have no idea what the business layer is doing or how it works.
We really pushed these principals on a project I worked on a few years ago. We had a reporting system that had to access 3 different databases, 2 3rd-party systems, and interface with business rules over 4 different departments and employees/sales in 3 different states. We created a custom data access layer that handled all of the data-related functionality for us. So in the business layer code, we never had to care about the data source, we had objects that represented the data in memory that all inherited from the same base data object/collection. Each specific report or functionality was based on one of 4 specialized frameworks that handled Crystal Reports, Office automation, work flow, and HTML generation. Each of the frameworks was based off of an even more basic type that handled the underlying multi-threading and work flow of the process. And all of that functionality was designed to be abstracted from the user interface so that we could build a Windows based interface to start with, and as the 3rd party apps gained more flexibility we could directly call our application's business logic and work flow from the other applications.
Anyway, one of the first projects I look at when stepping into a new project or job is to get the abstraction and design cleaned up. There is no sense beating on business logic when the underlying technology is going to cause you more headaches and piss off your users. And once you get that technology straightened out, you can focus on business logic and get the users a product that not only meets their needs, but also meets your needs in support and maintenance requirements.
-Rick
"Most people in the U.S. wouldn't know they live in a tyrannical state if it walked up and grabbed their junk." - MyFirs
is quite simple, actually.
First, if it's not invented here, then it's crap.
Second, I'm the only one I trust to write it correctly.
Third, I work alone, and I don't write comments - see number two.
If you do what you always did, you get what you always got.
Now, if Slashdot is his ONLY source, it's a different story. But I find that rather unlikely. This seems like a pretty good shot in the dark that might yield some interesting leads that he can research further.
Maybe it's just me, but exploring a wide variety of sources seems like GOOD research rather than poor.
It's been my experience that big software development companies almost invariably spend so much of their time worrying about those horrible real world conditions that it rarely occurs to them that those conditions didn't just happen by coincidence and that they could take steps to avoid the problems in the first place. Smaller shops tend to be much better at this.
Before anybody dives in and lectures me on scalability, let me say that IME the difference has a lot more to do with the kind of unprofessional, unproductive culture that can only thrive at mid-levels of large companies than anything to do with the scale of the project or the absolute size of the development team. Indeed, if you read the Bruce Webster article on a runaway project that was linked earlier today, it's pretty obvious that parts of the project code base were becoming unmanageably large because of incompetence and not because the project requirements actually necessitated that much code.
If you want to learn real world lessons, go watch a small- to medium-sized software shop, where there isn't space for the lazy and/or dictatorial idiots to hide, preferably one where everyone is a partner or there is some sort of profit-related pay so people have an incentive to really follow practices they think are helpful. Plenty of difficulties still arise in such environments, but they are much less likely to be own goals by the development team, and the team are much more likely to have effective ways to deal with them that would be of interest to others.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
Actually, when you realise what sort of horrors are present in a house you realise that the author of the linked document is drawing a false analogy. Both in houses, and in software, various shortcuts are taken for pragmatic reasons, and these are often because the shortcuts do not undermine what is the primary function of the "house" or the "software". For example, the concrete floor in my house is lousy rubbishy stuff. Probably doesn't meet the codes, yet except when the carpet layer has a hard time laying I never notice, nor really am I too concerned, about the failure to meet some "ideal" standard. So in doing research in this area, a reality check is required and the article you have chosen to refer to starts out with a poor example to prove a point ... I am not convinced.
// Comments.
Least universally usefulJohn
If you're looking for great software design principles, start with the greats: Liskov, Fowler, Martin. Go to Object Mentor's published articles, click on "Design Principles", and start reading.
These handful of articles changed the way I look at software, particularly OO software, but not necessarily restricted to OO, and highlighted the importance of controlling dependencies. All of the Gang of Four design patterns use one or more of the principles laid out in these white papers. I would go so far as to say that good architecture and design primarily revolves around managing dependencies correctly around your functional requirements and points of future extension, no matter what language you're in.
These concepts are going to become ever more important as we have to scale across more cores and more machines using functional languages like Erlang and Scala and techniques like map/reduce (see Hadoop, for Java).
but have you considered the following argument: shut up.
- I am also doing standard academic literature surveys, in several different ways.
- I am not conducting an opinion poll. I asked for links/references to known work.
- I am asking "the software development community" for input because software engineering is different from some other disciplines. It is unlikely a physics researcher would get new ideas about gravity from a public discussion forum. But there is a lot of good work about software engineering that does not come from the academic world, and is not published in academic journals. Some is not in printed format at all.
- If someone tells me an original idea, or a new take on an old idea, I will cite them in my paper.
- Asking people for ideas is not "getting someone else to do my homework for me". Anyone who thinks that it is has never done anything difficult.
Chuck Connell
Most bad software is rushed, created by bored programmers, in a corporate decision to create another boring and faulty-by-design software system.
Most good software is written by a small team of very excited developers who love what they do, are given the resources to do so, and who couldn't even think of a more exciting system to build.
You can add all the modularity or simplicity or readability or whatever you need, but unless it is made with love, it won't be beautiful.