Considering the Law of Demeter, Single Responsibility Principle and Tell, Don't Ask principle; What is the correct relationship between the Article and Comment class?
A: The Comment is a concern of Article class. It can Read, Create, Update and Delete comments. The Comment class itself is just a read-only representation of the Comment concept.
B: The Comment is a concern of HandleComments class. It can Create new comments and assign them to the respective articles. It can also Read, Update and Delete comments. The Comment class itself is just a read-only representation of the Comment concept.
C: The Comment is not a concern of neither Article or HandleComments classes. It has all the CRUD functionality by itself. It can Assign itself to an article as well.
D: The Comment could be a concern of either Article or HandleComments classes; However they can only Read, Create and Delete comments. The Update functionality is a concern of Comment class itself.
Update #1
Here is how I think about it, however can't really find answers because all of my reading ends up to a non-practical or very simple proof-of-concept examples:
Do I have to have readComment, createCommnet, updateComment and deleteComment classes? According to Bertrand Meyer classes with Verbal or PerformSomething names are signs of danger as they could be methods not classes. So it is okay to have only Article and Comment classes with all of their respective functionality inside themselves?
The Article and Comment doesn't have a is-a relationship, so obviously no inheritance here, but they have a has-a relationship. I'd go for Composition then, but who's responsible for what? If I am a Comment then this is my concern to Update myself, right? But is that the Article's concern to Delete me? Hence I'm attached to it.
Is it the concern of Article to load its Comments? Or there should be a man-in-the-middle class to handle the relationship between the Article and Comment? If the Comment has loaded by the Article then is it a concern of Article to be 100% responsible for all of the Comment actions?
Update #2
More thinking about it, what I really want is Loosely-Coupled classes as much as possible. In any case the Article class should have a list of Comments to iterate between them. In order to assign a Comment to an Article, I should either pass the Article reference to the Comment constructor -- the bottom-top way, or I should pass the Comment reference to the AddComment method of Article class -- the top-bottom way.
I prefer the Bottom-Top-Way, even tho it looks awkward in the first sight, because then I can have all the other Comment actions also within the Comment class itself, so the Article class will be totally unaware of Comments class. The only thing the Article class should have is an internal array to hold the Comments instances. No need to have AddComment, RemoveComment methods to the Article class.
Is it something that makes sense?
Without knowing a lot more about the system it's difficult to answer your question (bar the specifics in update 2). It's possible, for example, to think of comments referencing articles, or articles referencing comments. With more details, especially use cases, it's likely that one design would likely come out in front.
Nevetheless, in the absence of further information, it's your second bullet point, composition, which strikes me as most natural. To wit, articles have a list of comments, as well as a title, a body, etc. You might or might not have a CommentsList intermediate class. In any case, you can create, delete, and get references to comment objects. Comments have text, links, formatting, etc.
Re update 2, I agree that loose coupling is desirable. However I disagree that passing a reference to an Article to the Comment constructor makes sense, all other things being equal. This introduces a cyclic dependency -- because the Article has a list of Comments -- and also therefore a higher degree of coupling than would be the case if you took the alternative "top-bottom" approach of passing the Comment to the AddComment method of the Article class.
With this "top-bottom" approach, the Article could either have a NewComment method, in which case the Article itself creates the Comment object, or it could have an AddComment method as you suggest. Which is preferable depends on the details of the requirements: for example a requirement to have different kinds of comments (or even to share comments between articles) would suggest the AddComment approach.
Thanks to Bart comments, I decided to go for the Repository Design Pattern, which seems to be one of the battle-tested patterns for handling this kind of cases.
The general idea is to have a Repository which is responsible for taking care of Comments. So in a broader view a Blog should have at least a postRepository and commentRepository to take care of blog Posts and Comments functionality.
It is also recommended to handle all of the List like data with repository pattern, when there is a need for a kind of central-functionality. In the Blog example, it make sense to have repositories for Categories, Tags, Users, etc. as well.
Related
I have an abstract class "StrategyBase", and a set of sub classes, StrategyA/B/C etc. The sub classes use some of the properties of the base class, and have some individual properties. My question is how to save this to a database.
I'm currently using SqlCE, and Linq-To-Sql by creating entity classes automatically with SqlMetal.exe. I've seen there are three solutions shown in this question, but I'm not able to see how these solutions will work or not with SqlMetal/entity classes. Though it seems to me the "concrete table inheritance" would probably work without any manual modifying. What about the other two, would they be problematic?
For "Single Table Inheritance" wouldn't all classes get all variables, even though they don't need them? And for the "Class table inheritance" solution I can't really see at all how that will map into the entity-classes for a useful purpose. I may note that I extend these partial entity classes for making the classes of my business objects.
I may also consider moving to EntityFramework instead of SqlMetal/Linq2Sql, so would be nice also to know if that makes any difference to what schema is easy to implement.
One likely important thing to note is that I will constantly be develop new strategies, which makes me have to modify the program code, and probably the database shcema; when adding a new strategy.
Sorry the question is a bit "all over the place", but hopefully it's some clear advantages/disadvantages here that you may be able to advice. ?
Cheers!
Actually, this exact question gets asked an awful lot, and has been answered many times. You probably have not searched using database terminology.
The problem is applying OO terminology and thinking in a non-object subject area; making an ordinary straight-forward task very complex and limited.
Martin Fowler's and Scott Ambler's books are not worth a dollar for the lot of them, details in this answer, starting at the 11 Dec 10 entry.
If you still have questions, post a comment.
One option would be to make StrategyBase Serializable, then you can store it as a string in the database. I don't know how big the string would be, as it all depends on the size of your object, but you can make the database field nvarchar(1024) or even nvarchar(max). Ultimately this would result in the entire object being stored in a single table field as string.
Alternatively, as your link eludes to, you can just make a table that mimics each class, and each class object is a field in the table.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
This may simply be a matter of preference, however, I am interested to know what is the best-practise way of when to use either approach.
e.g.
var person = new Person();
person.Run();
as opposed to
var person = new Person();
Excercise.Run(person);
The above example may not be the best, but my general point is when should you decide to give the object the responsibility as opposed to another class?
Don't do things for your objects. They're there to do things for you.
That sounds quite simplistic, but it's a useful maxim to follow. It means (as you've identified) calling methods on an object and it will use all the knowledge available to it to produce a result. It reinforces encapsulation and separation/containment of responsibilities
An indicator that this is not happening is code like this:
priceBond(bond.getPrincipal(), bond.getMaturity(), bond.getCoupons(), interestRate)
where the bond object is yielding all it's information to some third party. Code like the above will end up beng duplicated everywhere. Instead write
bond.priceBond(interestRate)
and keep all the information tied up in the one object.
If your objects suffer from huge numbers of getters, then it's a possible indicator that your objects aren't doing what they're supposed to.
Generally speaking, this OOPish construct:
person.Run(distance);
is just a syntactic sugar for:
Person.Run(person, distance);
where person becomes an implicit this reference. There are some subtleties with virtual functions and such, but you get the idea.
As for your question, you're basically having a rich domain model versus an anemic one, and this is a subject of a great many debates.
Normally a class, in this case Person, has behaviour;
And in this case, the behavior is Run and thus the person should have the method Run
var p = new Person();
p.Run();
The first one carries so much more conceptual clarity. A person runs, a running exercise doesn't consume a person.
The comparision is ideally not correct for few reasons:
1. Ideally each object would be responsible for it's own activities for example in case of human, human would be responsible for human.walk(), human.eat(), human.sleep() etc.
2. The parameter that is being passed to the activity is a consumed resource for that activity. It would not be wise to say Life.walk(human), as walk is not Life's activity and human is not consumable resource. Here human is the object. However it would be wise to say human.eat(food); where food is a consumable resource.
3. The sample you have given seems to potray that in second case Run is a static method and for object functioning you rarely want to implement it as a static method design.
Ideally design patterns would guide you, if implemented correctly, that which way a function will be called on an instance, but mostly what will get passed to a method is a resource that is req. to do that activity and not the action object.
I hope that clears up your doubt. For more details on design patterns you can some books by Martin fowler.
http://www.martinfowler.com/books.html
If the it's the person's responsibility to Run then i would suggest person.Run()
if Run though can handle other types of objects and it's somehow reusable outside the person object then it could stand on it's own and call it as Excercise.Run(person);
For me, i would go with person.Run();
I agree with the first answer that if the act of running is best 'understood' by the person object then that is where it should reside, for both functionality and clarity.
The second case is more suited to interpretations outside of the object and is best performed through interfaces. So instead of taking a person object the Excersize methods should take an interface, say IExcersizable that, for example, moves limbs. The Excesize.run(IExersizable) method could move one leg and then the other in quick succession. The Excesize.walk(IExersizable) could to the same but slower.
The person objec could then implement the interface to deal with the specifics of 'limb' movement.
Two situations I can see where calling an static method on an object is the preferred approach are:If there is some realistic possibility that the passed-in parameter might not support the indicated action, and such occurrence should be handled gracefully. For example, it's often useful to have a function which will dispose an object if it's non-null and iDisposable, but harmlessly do nothing otherwise;If the method does something that really isn't broadly applicable to its parameters [e.g. testing if a person has a wristwatch made by some particular manufacturer; such functionality may be used often enough to merit its own method, but likely wouldn't really belong in the Person class, nor the WatchManufacturer class].
Some people like using extension methods for the former scenario. They can sometimes help clarity, but odd rules regarding their scope can sometimes cause confusion (if I had my druthers, extension methods would use a different syntax for invocation--something like theObject..theMethod--so it would be clear when extension methods were being used and when normal methods were).
There is a slight differences:
person.Run() receives a single parameter: this
if Excercise.Run(person) is a static method, it also receives a single parameter
if Excercise is an instance, it receives two parameters: this and person
Obviously the third approach is only needed if you have to pass both parameters. I would say the first approach is better OOP and I would only chose the second one in very special circumstances (for exmaple, if Person was sealed).
I agree with Brian. Just for reference, I wanted to point out this article on "Tell, Don't Ask" and "Law of Demeter". Both are applicable here.
Pragmatic Programmer: Tell, Don't Ask
Since a Person will be doing the running, it is better to have a run method in there.
Two things:
This is not a matter of taste but has actual technical consequences. The differences between a member function and a free function have been discussed at great length already, I recommend having a look at the Effective C++ book and/or an article by Scott Meyers at
http://www.ddj.com/cpp/184401197
In short, if you make a function a member function, you'd better have a darn good reason to do so.
The readability argument should be taken with care. It depends very much on the name of the member function. Remember the SPO - Subject Predicate Object rule: there's little doubt that person.run() looks better than run(person); (at least to an english-speaking person), but what if you have other verbs than 'run'. Some verb which takes an object, for instance 'to call' in case you want to make a phone call? Compare call( person ); vs. person.call();. The former looks much nicer.
I know there are LOTS of reasons why you would compose a certain object inside another one. Some schools of thought have made explicit the reasons for architecting a program a certain way e.g. 'data-driven design' or 'domain-driven design'. I'm still a beginner to OOP, and it's often hard for me to understand why one object should be contained by another. Sometimes, I find myself with an object that seems awesome, and then I get to the point where I realize, "Okay, now I have to put this somewhere?" Is the reasoning behind this similar to where I'd decide put a file on my hard disk?
I have a couple guiding principles for this:
If it models a relationship in the physical world.
If the composer has data needed to construct the object.
If the composed object will be listening to the composer.
What do you look for when you make this decision?
Well, one very simple concept that helped me with this is simply the concept of "has a" versus "is a". Ask yourself, is the contained object something the containing object has, or is it something the containing object is? If it's something the containing object has, then containment is appropriate. Otherwise maybe you should be looking at inheritance.
A dog IS an animal, and has a nose, so it's:
class Animal
{
}
class Dog : Animal
{
Nose n;
}
Now this works fine. One "problem" with this approach is that you tightly couple noses and dogs, so sometimes you'll see things like containing an interface pointer rather than an object, or you might Google "Dependency Injection". But as the saying goes, "has a" and "is a" is often close enough for government work.
Early on, just try lots of examples and over time it will become natural. If you end up with spaghetti, throw some meatballs at it and try again! :)
What alternatives are you considering? Are you talking about Containment versus Inheritance, John Lockwood's comments about hasA and isA help with that issue.
Or are your perhaps talking about, Containment versus Association? There are various flavours of hasA. For example a Person may haveA Spouse, but clearly does not containA Spouse. There's a difference between changing a Spouse and changing a Nose.
The kinds of relationship that you consider:
Lifetime: Does it make sense to create a Person without a Nose? Can Noses exist without a Person? Can a Person exist without a Spouse? The answers to these questions drive the kind of operation you choose to have on Person. Probably don't need a setNose() method, though maybe we do need a wipeNose() method, and we probably do need a marry(Person) method.
Cardinality: How many Noses for a Person? How many Wheels and Seats does a Vehicle have? Answers to this determine the kinds of data structures? Just a reference? A list? An hash table?
I found it helpful to read about UML modeling, especially class diagrams. This reflects much experience of how to usefully capture various kinds of relationships.
Sometimes, I find myself with an
object that seems awesome, and then I
get to the point where I realize,
"Okay, now I have to put this
somewhere?"
From the above sentence, it sounds like you're trying to design from the bottom up. One of the thing's I've learned over the years is that top down design is the way to go. You should only write the class after you know where it needs to be used. Otherwise you just end up writing classes that "seem awesome" and contain code that might not be useful at all.
I've read all the books about why to create a class and things like "look for the nouns in your requirements" but it doesn't seem to be enough. My classes seem to me to be messy. I would like to know if there are some sort of metrics or something that I can compare my classes to and see if there well designed. If not, who is the most respected OO guru where I can get the proper class design tips?
Creating classes that start clean and then get messy is a core part of OO, that's when you refactor. Many devs try to jump to the perfect class design from the get go, in my experience that's just not possible, instead you stumble around, solving the problem and then refactor. You can harvest, base classes and interfaces as the design emerges.
if you're familiar with database design, specifically the concept of normalization, then the answer is easy: a data-centric class should represent an entity in third normal form
if that is not helpful, try this instead:
a class is a collection of data elements and the methods that operate on them
a class should have a singular responsibility, i.e. it should represent one thing in your model; if it represents more than one thing then it should be more than one class.
all of the data elements in a class should be logically associated/related to each other; if they aren't, split it into two or more classes
all of the methods in a class should operate only on their input parameters and the class's data elements - see the Law of Demeter
that's about as far as i can go with general abstract advice (without writing a long essay); you might post one of your classes for critique if you need specific advice
Try to focus on behaviour instead of structure. Objects are 'living' entities with behaviour and responsibilities. You tell them to do things. Have a look at the CRC-card approach to help you model this way.
i think Object design is as much art as it is science. It takes time and practice to understand how to design clean & elegant classes. Perhaps if you can give an example of a simple class you've designed that you aren't happy with SO users can critique and give pointers. I'm not sure there are any general answers outside of what you've already read in the texts.
The most respected OO guru i personally know is StackOverflow. Put your classnames here and i reckon you'll get a goodly number of reviews.
Classes are typically used to model concepts of the problem domain. Once you have a well-defined problem (aka the set of use cases), you will be able to identify all participants. A subset of the participants will be intrinsic to the system you are designing. Start with one big black box as your system. Keep breaking it down, as and when you have more information. When you have a level where they can no longer be broken down (into concepts in your problem domain), you start getting your classes.
But then, this is a subjective view of a non-guru. I'd suggest a pinch of salt to the menu.
Metrics? Not so's that you'd trust them.
Are your classes doing the job of getting the program working and keeping it maintainable through multiple revisions?
If yes, you're doing ok.
If no, ask yourself why not, and then change what isn't working.
I know about "class having a single reason to change". Now, what is that exactly? Are there some smells/signs that could tell that class does not have a single responsibility? Or could the real answer hide in YAGNI and only refactor to a single responsibility the first time your class changes?
The Single Responsibility Principle
There are many obvious cases, e.g. CoffeeAndSoupFactory. Coffee and soup in the same appliance can lead to quite distasteful results. In this example, the appliance might be broken into a HotWaterGenerator and some kind of Stirrer. Then a new CoffeeFactory and SoupFactory can be built from those components and any accidental mixing can be avoided.
Among the more subtle cases, the tension between data access objects (DAOs) and data transfer objects (DTOs) is very common. DAOs talk to the database, DTOs are serializable for transfer between processes and machines. Usually DAOs need a reference to your database framework, therefore they are unusable on your rich clients which neither have the database drivers installed nor have the necessary privileges to access the DB.
Code Smells
The methods in a class start to be grouped by areas of functionality ("these are the Coffee methods and these are the Soup methods").
Implementing many interfaces.
Write a brief, but accurate description of what the class does.
If the description contains the word "and" then it needs to be split.
Well, this principle is to be used with some salt... to avoid class explosion.
A single responsibility does not translate to single method classes. It means a single reason for existence... a service that the object provides for its clients.
A nice way to stay on the road... Use the object as person metaphor... If the object were a person, who would I ask to do this? Assign that responsibility to the corresponding class. However you wouldn't ask the same person to do your manage files, compute salaries, issue paychecks, and verify financial records... Why would you want a single object to do all these? (it's okay if a class takes on multiple responsibilities as long as they are all related and coherent.)
If you employ a CRC card, it's a nice subtle guideline. If you're having trouble getting all the responsibilities of that object on a CRC card, it's probably doing too much... a max of 7 would do as a good marker.
Another code smell from the refactoring book would be HUGE classes. Shotgun surgery would be another... making a change to one area in a class causes bugs in unrelated areas of the same class...
Finding that you are making changes to the same class for unrelated bug-fixes again and again is another indication that the class is doing too much.
A simple and practical method to check single responsibility (not only classes but also method of classes) is the name choice. When you design a class, if you easily find a name for the class that specify exactly what it defines, you're in the right way.
A difficulty to choose a name is near always a symptom of bad design.
the methods in your class should be cohesive...they should work together and make use of the same data structures internally. If you find you have too many methods that don't seem entirely well related, or seem to operate on different things, then quite likely you don't have a good single responsibility.
Often it's hard to initially find responsibilities, and sometimes you need to use the class in several different contexts and then refactor the class into two classes as you start to see the distinctions. Sometimes you find that it's because you are mixing an abstract and concrete concept together. They tend to be harder to see, and, again, use in different contexts will help clarify.
The obvious sign is when your class ends up looking like a Big Ball of Mud, which is really the opposite of SRP (single responsibility principle).
Basically, all the object's services should be focused on carrying out a single responsibility, meaning every time your class changes and adds a service which does not respect that, you know you're "deviating" from the "right" path ;)
The cause is usually due to some quick fixes hastily added to the class to repair some defects. So the reason why you are changing the class is usually the best criteria to detect if you are about to break the SRP.
Martin's Agile Principles, Patterns, and Practices in C# helped me a lot to grasp SRP. He defines SRP as:
A class should have only one reason to change.
So what is driving change?
Martin's answer is:
[...] each responsibility is an axis of change. (p. 116)
and further:
In the context of the SRP, we define a responsibility to be a reason for change. If you can think of more than one motive for changing a class, that class has more than one responsibility (p. 117)
In fact SRP is encapsulating change. If change happens, it should just have a local impact.
Where is YAGNI?
YAGNI can be nicely combined with SRP: When you apply YAGNI, you wait until some change is actually happening. If this happens you should be able to clearly see the responsibilities which are inferred from the reason(s) for change.
This also means that responsibilities can evolve with each new requirement and change. Thinking further SRP and YAGNI will provide you the means to think in flexible designs and architectures.
Perhaps a little more technical than other smells:
If you find you need several "friend" classes or functions, that's usually a good smell of bad SRP - because the required functionality is not actually exposed publically by your class.
If you end up with an excessively "deep" hierarchy (a long list of derived classes until you get to leaf classes) or "broad" hierarchy (many, many classes derived shallowly from a single parent class). It's usually a sign that the parent class does either too much or too little. Doing nothing is the limit of that, and yes, I have seen that in practice, with an "empty" parent class definition just to group together a bunch of unrelated classes in a single hierarchy.
I also find that refactoring to single responsibility is hard. By the time you finally get around to it, the different responsibilities of the class will have become entwined in the client code making it hard to factor one thing out without breaking the other thing. I'd rather err on the side of "too little" than "too much" myself.
Here are some things that help me figure out if my class is violating SRP:
Fill out the XML doc comments on a class. If you use words like if, and, but, except, when, etc., your classes probably is doing too much.
If your class is a domain service, it should have a verb in the name. Many times you have classes like "OrderService", which should probably be broken up into "GetOrderService", "SaveOrderService", "SubmitOrderService", etc.
If you end up with MethodA that uses MemberA and MethodB that uses MemberB and it is not part of some concurrency or versioning scheme, you might be violating SRP.
If you notice that you have a class that just delegates calls to a lot of other classes, you might be stuck in proxy class hell. This is especially true if you end up instantiating the proxy class everywhere when you could just use the specific classes directly. I have seen a lot of this. Think ProgramNameBL and ProgramNameDAL classes as a substitute for using a Repository pattern.
I've also been trying to get my head around the SOLID principles of OOD, specifically the single responsibility principle, aka SRP (as a side note the podcast with Jeff Atwood, Joel Spolsky and "Uncle Bob" is worth a listen). The big question for me is: What problems is SOLID trying to address?
OOP is all about modeling. The main purpose of modeling is to present a problem in a way that allows us to understand it and solve it. Modeling forces us to focus on the important details. At the same time we can use encapsulation to hide the "unimportant" details so that we only have to deal with them when absolutely necessary.
I guess you should ask yourself: What problem is your class trying to solve? Has the important information you need to solve this problem risen to the surface? Are the unimportant details tucked away so that you only have to think about them when absolutely necessary?
Thinking about these things results in programs that are easier to understand, maintain and extend. I think this is at the heart of OOD and the SOLID principles, including SRP.
Another rule of thumb I'd like to throw in is the following:
If you feel the need to either write some sort of cartesian product of cases in your test cases, or if you want to mock certain private methods of the class, Single Responsibility is violated.
I recently had this in the following way:
I had a cetain abstract syntax tree of a coroutine which will be generated into C later. For now, think of the nodes as Sequence, Iteration and Action. Sequence chains two coroutines, Iteration repeats a coroutine until a userdefined condition is true and Action performs a certain userdefined action. Furthermore, it is possible to annotate Actions and Iterations with codeblocks, which define the actions and conditions to evaluate as the coroutine walks ahead.
It was necessary to apply a certain transformation to all of these code blocks (for those interested: I needed to replace the conceptual user variables with actual implementation variables in order to prevent variable clashes. Those who know lisp macros can think of gensym in action :) ). Thus, the simplest thing that would work was a visitor which knows the operation internally and just calls them on the annotated code block of the Action and Iteration on visit and traverses all the syntax tree nodes. However, in this case, I'd have had to duplicate the assertion "transformation is applied" in my testcode for the visitAction-Method and the visitIteration-Method. In other words, I had to check the product test cases of the responsibilities Traversion (== {traverse iteration, traverse action, traverse sequence}) x Transformation (well, codeblock transformed, which blew up into iteration transformed and action transformed). Thus, I was tempted to use powermock to remove the transformation-Method and replace it with some 'return "I was transformed!";'-Stub.
However, according to the rule of thumb, I split the class into a class TreeModifier which contains a NodeModifier-instance, which provides methods modifyIteration, modifySequence, modifyCodeblock and so on. Thus, I could easily test the responsibility of traversing, calling the NodeModifier and reconstructing the tree and test the actual modification of the code blocks separately, thus removing the need for the product tests, because the responsibilities were separated now (into traversing and reconstructing and the concrete modification).
It also is interesting to notice that later on, I could heavily reuse the TreeModifier in various other transformations. :)
If you're finding troubles extending the functionality of the class without being afraid that you might end up breaking something else, or you cannot use class without modifying tons of its options which modify its behavior smells like your class doing too much.
Once I was working with the legacy class which had method "ZipAndClean", which was obviously zipping and cleaning specified folder...