Related
In a sense NHibernate seems convenient because it leads to less typing, and then propably less errors.
I think NHibernate can be used in every size of application because it is really easy to use (especially with FluentNHibernate) and you it does much work for you like generating SQL
queries, mapping values to objects and so on. Even in typical small applications you need to put a great part of the whole effort on the data persistence layer, so why don't let NHibernate do the work for you?
Best Regards,
Oliver Hanappi
It is tough to judge what you are looking for based on the terseness of your question, as there is really a lot of nuance in an answer to this.
In many ways, as the others here say, it depends on your project and your knowledge of nHibernate. But it also depends on a lot of other factors as well...
If you think your small project might grow into a large project someday that could make a better argument for it as you then have a strong foundation on which to grow.
If your goal is learning nHibernate (or another ORM) then a small project may be the best place to get your feet wet and try it out. (Also try Linq2SQL, and other ORMs as well and go with what you find works the best for you.)
I personally use nHibernate for all of my projects large and small (where possible due to other constraints). But I've also been working with it for a while and a good base of code that I can reuse. So that factors into the time part of an answer. nHibernate has a pretty steep learning curve so if you need something done quick nHibernate may not be optimal.
I hope that helps, if you can refine your question and your goals a little more in your question it will assist the rest of us in getting you some better feedback and ideas to help you.
It depends what you mean by small, and how accomplished you are with Hibernate. I'd find that the extra overhead of getting set up would not make using it a good option on a little project personally. I'd say the same about other frameworks like Spring too, they are far more useful on larger projects with lots of developers.
It's not if you have a strong knowledge of NH, if you have some model generator, if you use some DBMS other than SQL Server.
I think that if you have a DB on SQL server, you're quin in a hurry, you are knowledgeable on LINQ, LINQ2SQL might be a good choice. Fast and RAD.
I agree with Oliver but would add the caveat that it is only easy to use once you know how (and that may take awhile). If you haven't gotten on top of the learning curve and need a simple app, NHib will slow you down; otherwise use it on anything that isn't completely trivial or a throw away! So your simple but effective app has one more sound piece of infrastructure as it scales and adapts to requirement changes.
HTH,
Berryl
I asked this question about Microsoft .NET Libraries and the complexity of its source code. From what I'm reading, writing general purpose libraries and writing applications can be two different things. When writing libraries, you have to think about the client who could literally be everyone (supposing I release the library for use in the general public).
What kind of practices or theories or techniques are useful when learning to write libraries? Where do you learn to write code like the one in the .NET library? This looks like a "black art" which I don't know too much about.
That's a pretty subjective question, but here's on objective answer. The Framework Design Guidelines book (be sure to get the 2nd edition) is a very good book about how to write effective class libraries. The content is very good and the often dissenting annotations are thought-provoking. Every shop should have a copy of this book available.
You definitely need to watch Josh Bloch in his presentation How to Design a Good API & Why it Matters (1h 9m long). He is a Java guru but library design and object orientation are universal.
One piece of advice often ignored by library authors is to internalize costs. If something is hard to do, the library should do it. Too often I've seen the authors of a library push something hard onto the consumers of the API rather than solving it themselves. Instead, look for the hardest things and make sure the library does them or at least makes them very easy.
I will be paraphrasing from Effective C++ by Scott Meyers, which I have found to be the best advice I got:
Adhere to the principle of least astonishment: strive to provide classes whose operators and functions have a natural syntax and an intuitive semantics. Preserve consistency with the behavior of the built-in types: when in doubt, do as the ints do.
Recognize that anything somebody can do, they will do. They'll throw exceptions, they'll assign objects to themselves, they'll use objects before giving them values, they'll give objects values and never use them, they'll give them huge values, they'll give them tiny values, they'll give them null values. In general, if it will compile, somebody will do it. As a result, make your classes easy to use correctly and hard to use incorrectly. Accept that clients will make mistakes, and design your classes so you can prevent, detect, or correct such errors.
Strive for portable code. It's not much harder to write portable programs than to write unportable ones, and only rarely will the difference in performance be significant enough to justify unportable constructs.
Even programs designed for custom hardware often end up being ported, because stock hardware generally achieves an equivalent level of performance within a few years. Writing portable code allows you to switch platforms easily, to enlarge your client base, and to brag about supporting open systems. It also makes it easier to recover if you bet wrong in the operating system sweepstakes.
Design your code so that when changes are necessary, the impact is localized. Encapsulate as much as you can; make implementation details private.
Edit: I just noticed I very nearly duplicated what cherouvim had posted; sorry about that! But turns out we're linking to different speeches by Bloch, even if the subject is exactly the same. (cherouvim linked to a December 2005 talk, I to January 2007 one.) Well, I'll leave this answer here — you're probably best off by watching both and seeing how his message and way of presenting it has evolved :)
FWIW, I'd like to point to this Google Tech Talk by Joshua Bloch, who is a greatly respected guy in the Java world, and someone who has given speeches and written extensively on API design. (Oh, and designed some exceptionally good general purpose libraries, like the Java Collections Framework!)
Joshua Bloch, Google Tech Talks, January 24, 2007:
"How To Design A Good API and Why it
Matters" (the video is about 1 hour long)
You can also read many of the same ideas in his article Bumper-Sticker API Design (but I still recommend watching the presentation!)
(Seeing you come from the .NET side, I hope you don't let his Java background get in the way too much :-) This really is not Java-specific for the most part.)
Edit: Here's another 1½ minute bit of wisdom by Josh Bloch on why writing libraries is hard, and why it's still worth putting effort in it (economies of scale) — in a response to a question wondering, basically, "how hard can it be". (Part of a presentation about the Google Collections library, which is also totally worth watching, but more Java-centric.)
Krzysztof Cwalina's blog is a good starting place. His book, Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, is probably the definitive work for .NET library design best practices.
http://blogs.msdn.com/kcwalina/
The number one rule is to treat API design just like UI design: gather information about how your users really use your UI/API, what they find helpful and what gets in their way. Use that information to improve the design. Start with users who can put up with API churn and gradually stabilize the API as it matures.
I wrote a few notes about what I've learned about API design here: http://www.natpryce.com/articles/000732.html
I'd start looking more into design patterns. You'll probably not going to find much use for some of them, but as you get deeper into your library design the patterns will become more applicable. I'd also pick up a copy of NDepend - a great code measuring utility which may help you decouple things better. You can use .NET libraries as an example, but, personally, i don't find them to be great design examples mostly due to their complexities. Also, start looking at some open source projects to see how they're layered and structured.
A couple of separate points:
The .NET Framework isn't a class library. It's a Framework. It's a set of types meant to not only provide functionality, but to be extended by your own code. For instance, it does provide you with the Stream abstract class, and with concrete implementations like the NetworkStream class, but it also provides you the WebRequest class and the means to extend it, so that WebRequest.Create("myschema://host/more") can produce an instance of your own class deriving from WebRequest, which can have its own GetResponse method returning its own class derived from WebResponse, such that calling GetResponseStream will return your own class derived from Stream!
And your callers will not need to know this is going on behind the scenes!
A separate point is that for most developers, creating a reusable library is not, and should not be the goal. The goal should be to write the code necessary to meet requirements. In the process, reusable code may be found. In that case, it should be refactored out into a separate library, where it can be reused in the future.
I go further than that (when permitted). I will usually wait until I find two pieces of code that actually do the same thing, or which overlap. Presumably both pieces of code have passed all their unit tests. I will then factor out the common code into a separate class library and run all the unit tests again. Assuming that they still pass, I've begun the creation of some reusable code that works (since the unit tests still pass).
This is in contrast to a lesson I learned in school, when the result of an entire project was a beautiful reusable library - with no code to reuse it.
(Of course, I'm sure it would have worked if any code had used it...)
I'm a vb.net developer in small IT department and I'm having trouble making the leap to programming exclusively with objects.
I understand the principles of OOP, design patterns, unit testing, etc, but when it comes to developing my applications, either my object design is poor, or I skip building with objects altogether. I know how to create unit tests, but don't have confidence in the ones I create.
I build almost exclusively data-driven data entry/reporting kind of apps. In most cases, much of the business logic is in the database in stored procedures and UDFs. I developer ASP.NET and Winforms applications to internal and external customers.
I've asked about small projects here on the Stack that I can look at to get an idea of good design and testing, but came up mostly short. I've read a bunch of books on design.
What are some good first steps toward breaking away from my old 'VB 6' ways?
Thanks!
A co-worker got me hooked on the book Domain Driven Design by Eric Evans. It really started to get me to move away from data driven development when nessasary.
Also getting involved in a .NET user group in your area will go along way in helping you find people who are more than willing to help you out.
I hear ya, man. I too, live in your world. A world where business people demand reports. Complex reports. Reports which are easily built with complex stored procedures. In this world it is easy to think that the database is king and it drives the application. That line of thought leads to complex database TSQL code, views, functions, and stored procedures.
Certainly if it is truly a report you need then a complex sql statement may be the answer. However, you want to know how to break out of that data-driven world and enter an object oriented world.
I think typical OO design tutorials won't do you justice. Who cares if a dog is a type of an animal and a German Shepherd is a type of dog. That doesn't explain how you do business at your job. Furthermore that is only an example of OO inheritance. Other OO patterns such as composition and dependency injection are much more useful most of the time.
The way I think you should approach your next project or task is to forget about the database temporarily. Pretend that you live in a magical world where getting data from the database doesn't have to happen and writing data back to the database also doesn't have to occur. You live in a world where your objects are always populated with the right data. Model your objects first in that abstract world. After doing so, then (and only then) concern yourself with the messy implementation details of getting and writing to the database. The database is only there to persist your data. Your data is alive because you've already modeled it to fit within the rules of your domain.
Understanding UML will help tremendously for this type of modeling. Use UML designs first to model your domain. Then code to those designs. Then work them to fit within the constrains of your database.
Eric Evans "Domain Driven Design" is a great book which hammers this and many other related points home. He makes the point that domain modeling is THE crucial element to successfully modeling an application. He goes on to point out that object oriented design lends itself better to domain modeling than any other type of programming paradigm.
Good luck. Once you embrace the fully modeled, fully typed world of objects, you'll never want to parse another dataset again.
Try to read code from projects that has been developed under OOP aproach.
Imagine how your code would looks like if you coding as the example that you are reading.
Be tough with your own code, try until you are satisfied and then when you read it after 3 months you'll find many other new things to improve it.
Remember the KISS rule, all the parts will fit as you still coding following the OOP principles.
Be disciplinated. It's easy to succumb to the old way but don't give up.
Remember Dijstra words:
...when you are doing something quick and dirty, you suddenly visualize that I am looking over your shoulders and say to yourself "Dijkstra would not have liked this", well, that would be enough immortality for me.
He lives inside each of us =). And you have done the most important thing, you really want to learn how. That's the main obstacle with VB6 developers when they change to VB.NET.
In VB6 it easier.
In VB6 always works faster.
It's the same thing...just looks better.
VB6 has a lot more functions.
Looks familiar?
There are two things I'd recommend:
Look into UML class diagrams and play around with the class diagram tool in Visual Studio. The purpose of OOP is to make things more "conceptual" by thinking in terms of objects and, at least for me, class diagrams help to do that.
Read through some good design patterns, like the Decorator or Factory method pattern. Since most design patterns take full use of object-oriented design and also are usually well described, they can really help get the concepts down.
I was in your shoes a few years back. I remember reading an article that estimated you would spend anywhere from 6 months to a year just reading about object-oriented development before you would start to "get it".
I started by just trying to introduce objects in my day-to-day procedural programming. Then I tried getting as much processing out of the UI as I could. Then I tried creating "layers" for my business logic and data access. I understand a lot of your business logic may already be in the database but it wouldn't hurt to have a BL layer in place in case that changed. Right now it can pretty much function as a pass through.
I have Eric Evan's Domain-Driven Design still to read but a couple of books that have helped me are "The Object-Oriented Thought Process" and the one that I'm currently reading, "Microsoft .NET: Architecting Applications for the Enterprise". This book, while maybe more than you really need right now, is the first that has helped me really understand the layers and how to implement them.
Anyway, good luck with your journey. Just remember, it's going to be a process, not a destination!
In addition to the advice given in the other answers, you should ditch the VB.NET and learn C#.
It won't do everything for you, but it will help you get out of your old ways of thinking.
I've been studying OOP for quite a while now and I have a good grasp of the theory. I read the Head First book on OOP and, while it reinforced a lot of the theory, I found the case studies to be somewhat trivial.
I find that I'm applying OOP principles to my code each day, but I'm not sure if I'm applying them correctly. I need to get to the point where I am able to look at my code and know whether I'm using inheritance appropriately, whether my object is cohesive enough, etc.
Does anyone have any good recommendations (books, online guides, blogs, walk-throughs, etc.) for taking the next step in developing solid OOP skills?
I am working primarily in .NET (visual basic), but I welcome suggestions that incorporate various platforms.
Read Refactoring by Martin Fowler, and apply it to your own work.
It will take you through a litany of malodorous characteristics of software code that describe how to detect improperly constructed classes, and even more importantly, how to fix them.
Consider looking into Design Patterns. Although it seems like they aren't commonly used in enterprise applications (I've seen them more commonly used in API's and Frameworks than embedded into enterprise code), they could be applied to make software simpler or more robust in a lot of situations if only developers knew how to apply them.
The key is to understand the design patterns first, then with experience you'll learn how to apply them.
There is a Head First book on design patterns that teaches the concept pretty simply, although if you want a book that really covers design patterns in detail, check out the Gang of Four design patterns book, which is basically what made design patterns mainstream and is referred to almost every time the topic is brought up.
Design patterns can be applied in pretty much any object-oriented language to some degree or another, although some patterns can be overkill or over engineering in some cases.
EDIT:
I also want to add, you should check out the book Code Complete 2. It's a very influential book in the world of software development. It covers a lot of different concepts and theories. I learn something new every time I read it. It's such a good book that if I read it every 6 months to a year, I look at it from a different perspective that makes me a better programmer just by re-reading it. No matter how much you might think you know, this book will make you realize just how little you really know. It's really a great book. I can't stress how much you should own this book.
If you already have the basics, I believe only experience will get you further. You say you are not sure if you are applying the principles correctly, but there is no one correct way. Code you write today, you'll look at in 6 months time, and wonder why you wrote it that way, and probably know of a better, cleaner way of doing it. I also guarantee that after 10 years, you'll still be learning new techniques and tricks. Don't worry too much about it, it will come, just read as much as you can, and try and apply what you read in small chunks.
I am currently half-way through the following book:
http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062
I cannot recommend this book strongly enough in terms of learning a real-life, professional-grade, practical approach to drafting and applying a well-formed and iterative design strategy before diving into code.
I, too, read the "Head First" book and felt that I was much better off for having read it.
After having a few years of working-world experience, I now view the Craig Larman book that I am recommending to be a perfect "next step" for me.
About the Presence of "UML" in this Book Title:
Whether you have positive feelings or negative feelings about UML notation, please do not let that influence your decision to buy the book (ISBN 0131489062) in either direction.
The prominence of "UML" in the title is misleading. While the author does use and explain UML notation, these explanations are extremely well-woven into relevant design discussions, and at no time does this book read like a boring UML spec.
In fact, here is a quote taken directly from the book:
What's important is knowing how to think and design in objects, which is a very different and much more valuable skill than knowing UML notation. While drawing a diagram, we need to answer key questions: What are the responsibilities of the object? Who does it collaborate with? What design patterns should be applied? Far more important than knowing the difference between UML 1.4 and 2.0 !
This book at times seems like it is "speaking to" a lead architect or a project manager. What I mean to say by that is that it assumes that the reader has significant control over the planning and direction of a software project.
Nonetheless, even if you are only responsible for some very small piece of your company's projects and products, I would still recommend this book and encourage you to apply some "scaled down" modifications of the book's advice to your piece of the project.
My OOP epiphany came from Grady Booch's book, way long time ago. Suddenly I realized why objects were good.
While polymorphism is cool, encapsulation is 75% of why objects are cool. It is sort of like an interface: you see the buttons but not the wiring. Before objects, only the most disciplined coders kept their grubby fingers off the internal bits of other people's procedures (it was called "structured programming").
Object make it easy to Do the Right Thing. Inheritance and polymorphism are little bonuses.
One way to learn about objects is to read other peoples' code. I learned a lot by reading the source code for the Delphi VCL framework. Even just looking at the documentation for Java will help you see what a single object class should do and how it is designed to be used by other objects.
Start a project of your own and pay attention when you want to sub-class your own classes and find that you have to go back and break up some protected methods so you can override just one piece of a process instead of replacing all of it. See how ancestors talk to descendants by calling abstract functions. In other words, go make a lot of mistakes and learn from them.
Enjoy!
Frankly, re-reading old David Parnas papers on information hiding helps me get in the right state of mind. The case studies may not be directly applicable but you should be able to get some useful generalizations out of them.
My epiphany happened when I tried to implement a very OO problem (dynamically and recursively building SQL statements) in VB6. The best way to understand polymorphism or inheritance is to need it and not be able to use it.
One thing that will definitely help you is working on a well-known, respected open source project. Either dig through the source code and see how things are done or try to make some additions / modifications. You'll find that there isn't one style or one right answer for most problems, but by looking at several projects, you'll be able to get a wide view of how things can be done. From there, you'll begin to develop your own style and will hopefully make some contributions to open source in the process.
I think you have to attempt and fail at implementing OO solutions. That's how I did it anyway. What I mean by fail is that you end up writing smelly code while successfully delivering a working solution. After it's written you'll get a feel for where things didn't quite feel right. You may have some epiphanies, and/or you may go and hunt for a slicker solution from other programmers. Undoubtedly you'll implement some variation of standard design patterns by accident. In hindsight, a light will click on (oh! so that's what a visitor is for), and then understanding will accelerate.
As others have said, I think tooling through some good OO open source code is a good idea. So is working with more experienced programmers who would be willing to critique your work. However understanding comes through doing.
You might want to try to read (and write) some Smalltalk for a while. Squeak is a free implementation that can show you the power of a fully object-oriented environment (unlike java or .net). All library code source is included. The language itself is incredibly simple. You'll find that java and c# are slowly adding the features well-known to Smalltalk since 1980.
Tortoise HG is extrodanarily well designed piece of OO open source software (written in Python).
If you already understand the basics, building something from scratch in a fully object oriented language will be a good step in fully understanding OOP software architecture. If you don't know Python, Python Essential Reference will take you through the language in full in a few days to a week.
After you understand the language take a look through the software above and you'll have all sorts of epiphanies.
To understand basically anything thoroughly, you need to have a decent knowledge of at least one abstraction level above and one level below it. In the case of OO, others have mentioned design patterns as the layer above OO. This helps a lot to illustrate why OO is useful.
As far as the layer below OO, try to play around with higher-order functions/late binding for a while and get a feel for how these relatively simple constructs are used. Also, try to understand how OO is implemented under the hood (vtables, etc.) and how it can be done in pure C. Once you grok the value of using higher order functions and late binding, you'll quickly realize that OO is just a convenient syntax for passing around a set of related functions and the data they operate on.
I've been quite used to working on small projects which I coded with 1,000 lines or less (pong, tetris, simple 3d games, etc). However as my abilities in programming are increasing, my organization isn't. I seem to be making everything dependent on one one another, so it's very hard for me to change the implementation of something.
Any ideas for keeping my code organized and being able to tackle large projects?
whiteboards are your best friends
prototype designs (not necessarily working prototypes, use notecards or other methods)
plan first! dont code until you know your requirements/goals
Sketch out an architectural design ahead of time. It doesn't have to be too detailed, but imagine how you want things to fit together in general terms.
Read into refactoring first (made famous by Martin Fowler).
By learning refactoring, you can learn how to write code which is easy to change, readable, and simplified.
I would suggest not to learn design patterns until you understand refactoring first. With refactoring, you can understand the themes of clean and readable code. Once you understand refactoring, read on to design patterns. Design patterns is very useful when you need to write more complex designs.
Use of design patterns is a good first step.
Also, spend a little time writing good documentation regarding system architecture and requirements for the application.
Using source control will help if you are not already doing this.
Look for libraries that may do want you want before you decide to roll your own.