Agile Principles, Patterns, and Practices in C#
All
Stack Overflow 30
This Year
Stack Overflow 3
This Month
Stack Overflow 11
When you are finished Clean Code I would recommend you read Bob Martin's other book:
In this book the vast ammount of the book discusses a case study and in it, Bob applies the principles discussed in Clean Code. I read Clean Code first but in retrospect I think "Agile Patterns.." should be read first as Clean Code is more of a day to day handbook or manual of good SW principles.
For example, in "Agile patterns..." the following code is used:
The following validation of the use of Public data deals with your question:
Aside:
Personally, I have to say that Robert Martin has made a massive contribution to the SW developer community (along with Martin Fowler, Michael Feathers..) with these books. I think they are must read.
Both patterns delegate to a base class that has several derivative, but it's only in the State pattern that these derivative classes hold a reference back to context class.
Another way to look at it is that the Strategy pattern is a simpler version of the State pattern; a sub-pattern, if you like. It really depends if you want the derived states to hold references back to the context or not (i.e: do you want them to call methods on the context).
For more info: Robert C Martin (& Micah Martin) answer this in their book, "Agile Principles, Patterns and Practices in C#". (http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258)
I strongly suggest not to start restructuring your application without a strong knowledge of SOLID principles and dependency injection. I did this mistake and now I have an application full of service locator (anti)pattern implementations that are not making my life simpler than before.
I suggest you to read at least the following books befor starting:
http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258 (for SOLID principles)
http://www.manning.com/seemann/ (for .NET dependency injection)
http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
A possible strategy is not refactoring just for the sake of it, but consider refactoring only the parts that are touched more than others. If something is working and nobody is going to change it there's no need to refactor it, it can be a loss of time.
Good luck!
Refactoring HTML is new and relatively good, you can guess what it covers :)
Other than that the two books you mention are the two I've used most, but Agile Principles is also very good.
Your qustion is very subject to opinion...
I love to abstract code and uncouple everywhere possible. The question, as always, is that of time and requirements.
For a small simple project that does not require extensive Unit Testing within the Business Tier, your coupling although does not necessarily follow best practice may be exactly what the customer/end-user requires, and may allow you to provide the software in a more timely fashion.
For a larger/more complex/etc project it may be best to abstract the persistance layer.
It is simply not feasible to follow best practices, best design patterns, and best coding principles for every line of code you write. I've found the authors of such books quite often mention the patterns as potentially surplus to requirements and should simply be used as a tool, when needed.
Hope that helps?
@BryanWatts is right. The classes presented by the OP violate the Liskov Substitution Principle. And you shouldn't use exceptions to control program flow—that's a code smell too. Exceptions are meant for, well, exceptions—exceptional conditions that will not allow your object to behave in an expected manner which could lead to corruption of your object's state and/or future behavior.
You need to ensure that you understand the totality of the Liskov Substitution Principle (LSP). LSP is not about ensuring that
interface
s can be used interchangeably.When an object inherits from another object, it's inheriting all of it's parent's behavior. True, you can override that behavior, but you must be careful in doing so. Let's use your example of a
Speaker
and aWirelessSpeaker
and see how it all falls apart.This is how your code broke the Liskov Substitution Principle (LSP). As Robert & Micah Martin astutely point out in Agile Principles, Patterns and Practices in C# on pp. 142-143:
By essentially having the precondition
TransmitterIsOn == true
for theBeep
method of theWirelessSpeaker
, you created a stronger precondition than what existed on the baseSpeaker
class. ForWirelessSpeaker
s, bothIsPlugged
andTransmitterIsOn
must betrue
in order forBeep
to behave as expected (when viewed from the perspective of aSpeaker
), even though aSpeaker
in and of itself has no notion ofTransmitterIsOn
.Also, you violated another SOLID principle, the Interface Segregation Principle (ISP):
In this case, a
WirelessSpeaker
does not need to be plugged in. (I'm assuming we're talking about the audio input connection here, as opposed to an electrical connection.) Therefore, theWirelessSpeaker
should not have any property calledIsPlugged
, yet, because it inherits fromSpeaker
, it does! This is an indication that your object model does not line up with how you intend to use your objects. Again, notice that most of this discussion is centered around the behavior of your objects, and not their relationship to one another.Moreover, the violation of both LSP and ISP both signal that there's probably been a violation of the Open/Closed Principle (OCP), too:
So, at this point it should be clear, now, that we do not use Code Contracts only to ensure that certain preconditions are met when calling methods on objects. No, instead Code Contracts are used to state guarantees (hence the word contract) about the behavior and state of your objects and their methods based on the stated pre- and post-conditions, as well as any invariants you may also have defined.
So, for your speaker class, what you're saying is: If the speaker is plugged in, then the speaker can beep. Ok, so far, so good; that's simple enough. Now, what about the
WirelessSpeaker
class?Well,
WirelessSpeaker
inherits fromSpeaker
. Therefore,WirelessSpeaker
also has anIsPlugged
Boolean property. Furthermore, because it inherits fromSpeaker
, then in order for theWirelessSpeaker
to beep, it must also have itsIsPlugged
property set totrue
. "But wait!" you say, "I have overridden the implementation ofBeep
such thatWirelessSpeaker
's transmitter must be on." Yes, this is true. But it also must be plugged in!WirelessSpeaker
not only inherits the Beep method, but also the behavior of its parent class's implementation! (Consider when a base class reference is used in place of the derived class.) Since the parent class can be "plugged in", so too, canWirelessSpeaker
; I doubt this is what you intended when you originally thought of this object hierarchy.So, how would you fix this? Well, you need to come up with a model better aligned to the behaviors of the objects in question. What do we know about these objects, and their behavior?
Ok, so the one piece of shared behavior these speakers have is they beep. So, let's abstract that behavior out into an abstract base class:
Great! Now we have an abstract base class that represents speakers. This abstract class will allow a speaker to beep, if and only if the
CanBeep()
method returnstrue
. And this method is abstract, so any class inheriting this class must provide their own logic for this method. By creating this abstract base class, we have enabled any class that has a dependency on theSpeakerBase
class to emit a beep from the speaker if and only ifCanBeep()
returnstrue
. This also resolves the LSP violation! Anywhere aSpeakerBase
can be used and called upon to beep, either aSpeaker
or aWirelessSpeaker
can be substituted and we can be sure of the behavior: if the speaker can beep, it will.Now all that's left is to derive each of our speaker types from
SpeakerBase
:So, now we have a
Speaker
that can only beep when it's plugged in. We also have aWirelessSpeaker
that can only beep if it's transmitter is turned on. In addition,WirelessSpeaker
s know nothing about being "plugged in". It's simply not a part of their essence.Furthermore, following the Dependency Inversion Principle (DIP):
What this means is that consumers of speakers should not depend directly on either
Speaker
orWirelessSpeaker
, but should depend onSpeakerBase
instead. This way, no matter what kind of speaker comes along, if it inherits fromSpeakerBase
, we know that we can beep the speaker if the conditions warrant for the sub-type of speaker referenced by the abstract type in the dependent class. This also means thatIBeepSpeakers
no longer knows how to put a speaker in the state such that it can beep, as there is no common behavior among speaker types thatIBeepSpeakers
could use to make such a determination. So that behavior must be passed in as a dependency toIBeepSpeakers
. (This is an optional dependency; you could just let the class take in aSpeakerBase
and callBeep()
, and, if theSpeakerBase
object is in the correct state, it'll beep, otherwise it won't.)As you can see, we actually didn't need Code Contracts at all to tell us whether or not the speaker should beep. No, rather we let the state of the object itself determine whether it can beep.
In my opinion, Null is preferable over throwing an Exception, but that depends on how exceptional this case is, and of course your domain.
A nicer thing to return is a Null object, i.e. an Object that implements the same Interface as the item you are looking up in your repository, but it has behaviour that makes it nicer to work with than just null.
Read up on the Null object pattern, or look it up in Agile Principles, Patterns, and Practices in C#
Based on your examples, there's definitely an ISP and a SRP and probably a Law of Demeter (not SOLID but...) violation going on at the very least.
IMNSHO You're far better off reading articles on SOLID (or buying Agile Principles, Patterns, and Practices in C# by Robert C. Martin and Micah Martin which is excellent throughout and one of the most useful books I've read in recent years) than asking for piecemeal advice on the interwebs for this type of thing.
If you want a shortcut (you don't though - the books and PDFs have examples that explain things very well!), these Hanselminutes podcasts with Uncle Bob are very good:
edit: Nabbed the SRP from Jon Limjap and ppiotrowicz
This is certainly a reasonable explanation:
http://en.wikipedia.org/wiki/Inversion_of_control
I own this book: I'd recommend it for good coverage of many design principles, including IoC:
Agile Principles, Patterns and Practices in C#: Martin Fowler, Micah Fowler
You might also find these links helpful:
DI and IOC examples in simple C#
Inversion of Control < Dependency Injection
Two pithy "explanations":
IoC is sometimes known as the "Hollywood Principle": Don't call us, we'll call you
IoC = Marriage; IOC Container = Wife
This sounds an integration test to me. Anyways, forget RhinoMock in this case because there's no other way to do it but to create your own test suite here. In our case we actually used HttpClient to call the controller/api and pass the url and argument needed for action and anticipate the result for validation.
Now you can use it in your actual testing.
There are a lot of missing configuration and setup here but the gist is there.
Update : I really like what you are currently doing in the name of testing because this is a powerful tool as part of Continues Integration (CI). Just a minor comment the way to name your test method. I would suggest to rename the test method into an action you want to do and put those procedure inside the test like what Gherkin way of BDD or as described by Dan North .
If you can create a TestSuite like described above it will give you a lot of benefits in the long run and avoid repetition of code (DRY). Also those tests will serve as living documents as described by Robert C. Martin & Micah Martin. Special thanks to the team that Im involved and kudos is for them!
I advise you to take note of a book Agile Principles, Patterns, and Practices in C# by
Robert C. Martin
andMicah Martin
, there are many good examples where it is shown how to design a system byUML
, and other similar methods. Specifically, it is shown why you should refactor your code, that can be stored in abstract classes and what is not. You can immediately see an example with a coffee makerMark IV
, where he developed a truly independent interface.According to my feelings, the main principle of MVVM - is the independence of the data from its representations. I like trying to make separate modules, which implement separate logic, not knowing about the data. For example, SQL module, SMTP module, etc, which simply contain some methods like
ConnectToDb()
orSendEmail()
, the main logic is inViewModel
, she combines these Work-modules with the data model.Useful to draw a diagram before designing the system, but do not get involved too. The main thing is to see the main parts in the paper, and that the others would understand it as well as you know (or architect).
First of all, it is this book:
http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258/ref=sr_1_5?ie=UTF8&qid=1308502374&sr=8-5
Robert Martin - it is a person who introduced SOLID principles.
You will want to learn more about the entire Agile Development movement. Agile is just what it says: able to quickly adapt.
Robert C. Martin's 2002 book - a classic.
Agile in C# - this is what I use
See this list of books
You'll want to read the Agile Manifesto!
Just one more: Kent Beck's work - especially Test-Driven Development.