I'm taking further intro java classes at the moment and this is how the class briefly defined this:
Cohesion: Aim for high cohesion, in this case cohesion meaning that a single module is tightly focused on its task.
Coupling: Aim for low coupling, in this case coupling meaning the level of extent in how intertwined two or more modules are.
How does one determine the level of cohesiveness as well as coupling?
For instance, some of my methods call other methods that are in the same class. This means that the method that calls other methods are dependent on the other methods in order for the "calling" method to finish its code block. Does this mean that I have low cohesion and high coupling on the methods of the same class? Or do these concepts refer more to different classes and different packages?
Cohesion and decoupling are important at all levels: each line of code should have a specific meaning and purpose, each method should have a specific meaning and purpose, each class should have a specific meaning and purpose, each package should have a specific meaning and purpose, each code repository should have a specific meaning and purpose.
This doesn't mean that a method shouldn't call another method, that a class shouldn't use another class, etc.; rather, it means that ideally, you should be able to read and understand a method without reading every other method it calls, to read and understand a class without reading every other class it uses, etc.
That said, we expect greater cohesion and decoupling for larger units: classes need to be much more cohesive and much less tightly coupled than methods do, for example, because assuming your classes are a reasonable size, you can much more easily go back and forth between methods than between classes when you're reading and maintaining the code.
There are metrics for cohesion / coupling; see https://softwareengineering.stackexchange.com/questions/151004/are-there-metrics-for-cohesion-and-coupling.
So the way to "determine" the level of cohesion / coupling is to implement a tool that measures the respective metrics. (Or find an existing tool that does this. For example, Sonar.)
How does one determine the threshold for the level of cohesion and/or coupling?
I assume you mean ... how do you decide when you will call values of the respective metrics "unacceptable" in your codebase.
Basically, that is up to you to decide. I would do it by looking at examples where the tool is reporting a "bad" value, and decide how bad I thought it really was. Alternatively, stick with the default thresholds in the tool that you are using.
I might be wrong, but here is just my humble input.
Cohesion is often time mentioned along with coupling, but they have an inverse relationship. High cohesion == low coupling.
Let me quote you
Aim for high cohesion, in this case cohesion meaning that a single
module is tightly focused on its task.
So it just means like that. Something that only does one thing and does it well. For example, a method to save an entity to the database should only focus on how to save that entity to the database, it should not worry about the correctness of that entity (Do all of that entity instance attributes pass all the database schema validations, in which case this validation should be handled maybe by an interceptor).
Coupling refers to the degree to which 2 modules depend on each other, the least the better because it promotes maintenance, and re-usability, etc. Often time, low coupling is achieved by using events, we have event emitters and event consumers, and they don't have to know anything about each other. Even emitters just fire-and-forget, and the consumers will take of the events when the system delivers the events to them.
Related
I am reading Head First Design pattern and just stuck on the Hollywood Principle. Earlier I read about Inversion of Control and what I understood was, it's a design principle (some also call it pattern) through which conventional flow of program changes from "Higher level module calling Lower level module" to "Lower level module calling Higher level module" (generally through abstractions), so we can have very low dependency on specific low-level module and changing low-level modules does not have any impact on our higher level or near to business modules.
But I got confused when the author said the following line regarding the Hollywood principle:-
On page 296
With the Hollywood Principle, we allow low-level components
to hook themselves into a system, but the high-level
components determine when they are needed, and how. In
other words, the high-level components give the low-level
components a “don’t call us, we’ll call you” treatment.
In the last line, it is said that The high-level components give the low-level
components a “don’t call us, we’ll call you” treatment. This means our high-level components are actually calling low-level components and hence
this seems to break the Inversion of control principle and also Dependency Inversion principle.
Please clarify on this.
The seeming contradiction is cleared up if we focus on a different part of the Dependency Inversion Principle:
A. High level modules should not depend on low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
That adds some context that clears up the potential confusion created by this statement:
The high-level components give the low-level components a “don’t call us, we’ll call you” treatment.
The high-level components don't directly deal with the low-level components at all. They deal with abstractions that represent the purpose or function of the low-level components.
So it doesn't "break" the Dependency Inversion Principle. Rather, it just needs to be understood in harmony with that principle. They are two different principles, so we could apply one and break the other. But if components communicate with each other as represented by abstractions then we can apply both.
They could have added that clarification into the sentence in question, but it would have made it wordier and more confusing.
FWIW I often find the terms "high level" and "low level" confusing because we don't tend to use them except when discussing the Dependency Inversion Principle. Whether a component is "high level" or "low level" the recommendation is to depend on abstractions. In other words, depend on abstractions. We can apply the principle without classifying components as high level or low level.
When we design software we implement two things API and Framework.
An API publish some endpoint so that caller uses those endpoints to get some useful information, so the caller doesn't have any action point to take, only endpoints and outputs.
The framework takes the strategy or business implementation from the caller and calls it when required.
In Hollywood Principle, we can feed our strategy or business implementation, denoting the framework implementation, which calls the fed strategy when required.
Inversion of control and Dependency Injection is to remove dependencies of an application. This makes the system more decoupled and maintainable.
If you go back to old computer programming days, program flow used to run in its own control.
if you analyze the program flow closely, it’s sequential. The program is in control of himself. Inversion of the control means the program delegates control to someone else who will drive the flow.
class Customer {
public function getCustomers() {
$conn = new MySQLConnection();
return $conn->getCustomers();
}
public function iocCustomers(MySQLConnection $conn) {
return $conn->getCustomers();
}
}
In the case of getCustomers(), we are creating the Database object inside Customer classes function - deeply coupled. Whenever the Customer object is created, the MySQLConnection object also will be created, which is not required.
If you consider the iocCustomers(), when we call the function we are passing the Database object as well. Here the Customer class is not concerned about the database till it need the data, it will use it when it required. Like, you no need to be in Hollywood to get a chance, when you needed they will call you, like, MySQLConnection object is injected to the function where it required by the class Customer.
Here two things are happening.
Customer class no need to worry/know about who provides the data. In other words, the client/calling class Customer doesn't have control over the data. [SRP in SOLID principles]
The connection object gets the control over the data and it can decide from which database(MySQL or SQLite) it need to provide data. If we create the object MySQLConnection in the getCustomers(), it will not get the flexibility to switch. This is called Inversion of Control. Taking the control from the caller to the class who generates the data.
Note: In the case of second function there are some advantages.
We can pass an interface called DBConnectionContract to iocCustomers() instead of MySQLConnection. So that we can pass any database object(MySQL, Sqlite, Postgres) which implements DBConnectionContract interface. This will help us to switch the database to one another with minimum modifications.
Modifications can be like below:
interface DBConnectionContract {}
class MySQLConnection implements DBConnectionContract {}
class SQLiteConnection implements DBConnectionContract {}
class Customer {
public function iocCustomers(DBConnectionContract $conn) {}
}
Another advantage is related to Unit testing. To the iocCustomers() we can pass mock database object while unit testing. Because to do the unit test of a function we need to make the environment needed for that function to execute.
The Hollywood Principle is not at odds with the Inversion of Control, although it can be programmed ignoring it.
In the book the Coffee example (I guess one page later, I have another edition) sub-classes two methods that get called via the Hollywood Principle. If the sub-classes just overwrites some abstract methods from the base class it does not really uses the Inversion of Control.
However since the called sub-class can adjust members of the base class it can take control that way. In the Q and A in my book one page earlier it explains a bit in the question: What are hooks really supposed to be used for. I will try to explain.
Say if you have a base class with an unsorted list and a call to print() the list. If you have a sub-class which via a hook can be called to overwrite print() that sub-class might decide to first sort the actual list of the base class and than call other functions if needed. In this way the low level function can take over control from the high level function.
IoC is sometimes referred to as the Hollywood Principle. They are the same... but, like all idiomatic expressions, it is always subject to semantics. The principle of controlling low-level dependencies from higher level abstractions is not "a pattern", it is a principle. It is also not exemplified well by associating that principle solely with sub-classing, though there it does most naturally exist.
More commonly it is accomplished through composition/aggregation by holding a reference to some Interface or abstract type in a low-level object and injecting dependencies into that class. It has no control or responsibility for what it receives, it only knows how to process it.
In other words, it (low-level) must wait by the phone, rather than call for its next screening, audition? what ever they call that in Hollywood.
Situation: Suppose we're designing the UI of Windows 9 using Java API. We need to build up 3 classes main, BuildInWindow and ApplicationWindow.
main - the window for rendering the system UI (i.e. the start botton & wallpaper page)
BuildInWindow- windows for rendering buildt-in apps (e.g. IE)
ApplicationWindow- windows for rendering apps from third party (e.g. eclipse)
all of them have to implement 3 Java API interfaces, WindowFocusListener, WindowListener and WindowStateListener and have the methods onExit() and onCrushing().
onExit() performs when the system/built-in app/ third-party app is shut down normally
onCrushing() captures any system/application crush and send system state back to server
This is the original design:
http://i.stack.imgur.com/JAJiY.png
I have some ideas of how to design it in a OO manner, but I am not sure if that's the right way. Here's my thoughts:
Create an abstract class with method onExit() and onCrushing(). Since the code of onExit()would vary from 3 classes, it should be an abstract method & onCrushing()would be same fo all classes, so it would be an concrete method
tHE MAIN WINdow should use singleton design to ensure user only create one instance of main.
Use the facade design to save the trouble of implementing 3 interfaces to three classes
My question is I don't really understand facade design, so I am not sure if it can be applied in this case. Also I am not really sure if onExit() would be different for 3 classes and onCrushing() would perform the same function.
I tried my best to explain the question clearly...if you don't understand free free to comment. Thank you very much!
I've left some questions in a comment linked to your question but here's some guidance for you:
You shouldn't create an abstract class on the basis of both BuildInwindow and ApplicationWindow both having to have methods #onExit and #onCrushing if they are not to share any implementation. Abstract classes are most useful where there is a common implementation. An interface containing these methods would be sufficient. That said, your two windows may share other functionality and, if so, it could be shared through a common superclass (abstract if it relies on subclass implementation detail). You may find the Template Method pattern useful for managing the overall window mechanism with specific tailoring for different window types. You may also find the Factory Method means of instance creation (for your window classes) will help separate the object creation and set-up from the creation mechanism.
A single shared instance would seem sensible and a singleton would serve this purpose (so long as you're able to handle termination, etc). Alternatively, your application may just launch a single Main instance - you may even just hide the constructor through package access to ensure no others are created.
The facade pattern just serves to simplify a complex interface. It mainly does this by rolling calls to collaborating instances together under a single (coarser) interface. This wouldn't normally be a done to hide which interfaces a class supports. Indeed, publishing which interfaces a class extends is important to API users. You could roll the three interfaces into a single interface for "convenience" but I think this is unnecessary. If you do settle on a common superclass then that would "extend" the three interfaces (if all subclasses were expected to support them). It may also implement some default implementation of these interfaces (again, watch access modifiers to ensure those you intend to be can be overridden while others may be final).
Edit: Guidance
You just have to identify the classes and relationships:
I suggest you just grab some paper and draw. You already have your nouns and verbs (you can otherwise go noun and verb spotting to identify classes and methods on them).
So, why not draw a simple diagram containing all the info (A, B, C, Main, etc) and draw the relationships between them. This is your start point. You may have some confusion when working out how Main links to the window classes (given there are two kinds). Just write a note on it and move on to clarify the rest of the picture.
Next, refine your diagram to start moving common features into a single place (abstraction). You know this exists with regards to your interfaces and the methods you suggest but you may need to decide which (if any) have any common functionality. Then decide if interfaces satisfies your needs (methods are common but implementations are different) or if the implementation itself is the same and so a parent superclass may be useful (this addresses abstraction [who is responsible for what], encapsulation [individual implementations at the appropriate level] and polymorphism [which classes support common methods]). Note that, even if you settle on an superclass, you'd be wise to back it with an interface (it makes introduction of sibling or replacement classes easier in time - think maintenance).
Next, work on the issues you found. Has your draft design clarified any of them? For instance, your Main needs to know about its windows but - what type are they? So, has any of your refinement made this clearer?
Do any patterns present themselves? for this you need to already have a feel for design patterns I'm afraid so buy and absorb the GoF Design Patterns book. It'll put you in good stead for spotting patterns as you go. I'd also recommend reading this specific book before taking on any others as it's technology agnostic (and some other books arebloated with tech-specific workarounds). Perhaps study the two patterns I pointed out and see if they fit your requirement.
On the whole though, your ideas seem to be going in the right direction.
To my knoweldge so far I thought that coupling relates to the degree in which two or more classes are "interconnected". In other words in which extent a class makes use of methods or variables of other classes. Our goal in a well designed Software System is of course to keep the coupling low (loose).
I am reading though currently a book, which states explicitly, that the objective of loose coupling is achieved by designing the System, so as every class to use only the API (public methods) of other classes and not directly their instance variables. Consequently the instance variables must be private. If that is the point, what is the difference between loose coupling and strong encapsulation? As far as I am concerned the later refers to encapsulation. What is actually true regarding the above notions of OO Software Development?
Loose coupling is more than just using a public API, it's also an ability to understand only that API, and not be dependent on specific implementations. It also includes limiting the amount of change required in dependent code across implementation differences.
Encapsulation isn't just about disallowing direct property access. It also includes making sure that internal data isn't exposed in a way that can cause unintentional behavioral (e.g., returning defensive copies of internal structures), and ensuring behavior, not just data, is properly isolated, and responsibilities are implemented in appropriate places.
Loose coupling is properly achieved by the judicious application of strong encapsulation. Weak encapsulation may provide loose coupling but may also introduce loopholes that allow for visibility of methods and variables outside of the abstraction's scope (inadvertant tight coupling). Strong encapsulation however, does not imply anything about coupling since a class of this nature can be designed to couple loosely, tightly, or not at all with external entities.
You may achieve loose coupling with strong encapsulation but encapsulation itself does not yet guarantee good code and loose coupling. Despite encapsulation you may still write tightly coupled code.
Loose coupling (a rule that no unnecessary dependencies between objects/modules are introduced) may be achieved without formal encapsulation (accessors/setters and restricted visibility).
But... If you write code for yourself or for a small set of skilled co-developers then referring directly to class members (thus breaking encapsulation) may facilitate keeping code smaller and easier to read and understand. C# has partially done it with properties - they look like plain class members but are in fact accessors and setters.
For bigger teams or reusable code I would say that strong encapsulation is a must. However you should always keep in mind flexibility - if you restrict your API too much it will become unusable. This is especially important if your code is not yet mature enough to handle all use cases with "official" API.
Whilst there are many good examples on this forum that contain examples of coupling and cohesion, I am struggling to apply it to my code fully. I can identify parts in my code that may need changing. Would any Java experts be able to take a look at my code and explain to me what aspects are good and bad. I don't mind changing it myself at all. It's just that many people seem to disagree with each other and I'm finding it hard to actually understand what principles to follow...
First, I'd like to say that the primary reason you get such varying answers is that this really does become an art over time. Many of the opinions you get don't boil down to a hard fast rule or fact, more it comes down to general experience. After 10-20 years doing this, you start to remember what things you did that caused pain, and how you avoided doing them again. Many answers work for some problems, but it's the individual's experience that determines their opinion.
There is really only 1 really big thing I would change in your code. I would consider looking into what's called the Command Pattern. Information on this shouldn't be difficult to find either on the web or in the GoF book.
The primary idea is that each of your commands "add child", "add parent" become a separate class. The logic for a single command is enclosed in a single small class that is easy to test and modify. That class should then be "executed" to do the work from your main class. In this way, your main class only has to deal with command line parsing, and can lose most of it's knowledge of a FamilyTree. It just has to know what command line maps into which Command classes and kick them off.
That's my 2 cents.
I can recommend Alan's and James's book Design Patterns explained -- A new perspective on object-oriented design (ISBN-13: 978-0321247148):
It's a great book about has-a and is-a decissions, including cohesion and coupling in object-oriented design.
In short:
Cohesion in software engineering, as in real life, is how much the elements consisting a whole(in our case let's say a class) can be said that they actually belong together. Thus, it is a measure of how strongly related each piece of functionality expressed by the source code of a software module is.
One way of looking at cohesion in terms of OO is if the methods in the class are using any of the private attributes.
Now the discussion is bigger than this but High Cohesion (or the cohesion's best type - the functional cohesion) is when parts of a module are grouped because they all contribute to a single well-defined task of the module.
Coupling in simple words, is how much one component (again, imagine a class, although not necessarily) knows about the inner workings or inner elements of another one, i.e. how much knowledge it has of the other component.
Loose coupling is a method of interconnecting the components in a system or network so that those components, depend on each other to the least extent practically possible…
In long:
I wrote a blog post about this. It discusses all this in much detail, with examples etc. It also explains the benefits of why you should follow these principles. I think it could help...
Coupling defines the degree to which each component depends on other components in the system. Given two components A and B ,how much code in B must change if A changes.
Cohesion defines the measure of how coherent or strongly related the various functions of a single software component are.It refers to what the class does.
Low cohesion would mean that the class does a great variety of actions and is not focused on what it should do. High cohesion would then mean that the class is focused on what it should be doing, i.e. only methods relating to the intention of the class.
Note: Good APIs exhibit loose coupling and high cohesion.
One particularly abhorrent form of tight coupling that should always be avoided is having two components that depend on each other directly or indirectly, that is, a dependency cycle or circular dependency.
Detailed info in below link
http://softwarematerial.blogspot.sg/2015/12/coupling-and-cohesion.html
We are following Domain Driven Design for the implementation of a large website.
However by putting the behaviour on the domain objects we are ending up with some very large classes.
For example on our WebsiteUser object, we have many many methods - e.g. dealing with passwords, order history, refunds, customer segmentation. All of these methods are directly related to the user. Many of these methods delegate internally to other child object but
this still results in some very large classes.
I'm keen to avoid exposing lots of child objects
e.g. user.getOrderHistory().getLatestOrder().
What other strategies can be used to avoid this problems?
The issues you are seeing aren't caused by Domain Driven Design, but rather by a lack of separation of concerns. Domain Driven Design isn't just about placing data and behavior together.
The first thing I would recommend is taking a day or so and reading Domain Driven Design Quickly available as a free download from Info-Q. This will provide an overview of the different types of domain objects: entities, value objects, services, repositories, and factories.
The second thing I would recommend is to go read up on the Single Responsibility Principle.
The third thing I would recommend is that you begin to immerse yourself in Test Driven Development. While learning to design by writing tests first won't necessarily make you designs great, they tend to guide you toward loosely coupled designs and reveal design issues earlier.
In the example you provided, WebsiteUser definitely has way too many responsibilities. In fact, you may not have a need for WebsiteUser at all as users are generally represented by an ISecurityPrincipal.
It's a bit hard to suggest exactly how you should approach your design given the lack of business context, but I would first recommend doing some brain-storming by creating some index cards representing each of the major nouns you have in your system (e.g. Customer, Order, Receipt, Product, etc.). Write down candidate class names at the top, what responsibilities you feel are inherent to the class off to the left, and the classes it will collaborate with to the right. If some behavior doesn't feel like it belongs on any of the objects, it's probably a good service candidate (i.e. AuthenticationService). Spread the cards out on the table with your colleges and discuss. Don't make too much of this though, as this is really only intended as a brainstorming design exercise. It can be a little easier to do this at times than using a whiteboard because you can move things around.
Long term, you should really pick up the book Domain Driven Design by Eric Evans. It's a big read, but well worth your time. I'd also recommend you pick up either
Agile Software Development, Principles, Patterns, and Practices or Agile Principles, Patterns, and Practices in C# depending on your language preference.
Although real humans have lots of responsibilities, you're heading towards the God object anti-pattern.
As others have hinted, you should extract those responsibilities into separate Repositories and/or Domain Services. E.g.:
SecurityService.Authenticate(credentials, customer)
OrderRepository.GetOrderHistoryFor(Customer)
RefundsService.StartRefundProcess(order)
Be specific with naming conventions (i.e. use OrderRepository or OrderService, instead of OrderManager)
You've run into this problem because of convenience. i.e. it's convenient to treat a WebsiteUser as an aggregate root, and to access everything through it.
If you place more emphasis on clarity instead of convenience, it should help separate these concerns. Unfortunately, it does mean that team members must now be aware of the new Services.
Another way to think of it: just as Entities shouldn't perform their own persistence (which is why we use Repositories), your WebsiteUser should not handle Refunds/Segmentation/etc.
Hope that helps!
A very simple rule of thumb to follow is "most of the methods in your class HAVE to use most of the instance variables in your class" - if you follow this rule the classes will be automatically of the right size.
I ran into the same problem, and I found that using child "manager" objects was the best solution in our case.
For example, in your case, you might have:
User u = ...;
OrderHistoryManager histMan = user.getOrderHistoryManager();
Then you can use the histMan for anything you want. Obviously you thought of this, but I don't know why you want to avoid it. It seperates concerns when you have objects which seem to do too much.
Think about it this way. If you had a "Human" object, and you had to implement the chew() method. Would you put it on the Human object or the Mouth child object.
You may want to consider inversing some things. For example, a Customer doesn't need to have an Order property (or a history of orders) - you can leave those out of the Customer class. So instead of
public void doSomethingWithOrders(Customer customer, Calendar from, Calendar to) {
List = customer.getOrders(from, to);
for (Order order : orders) {
order.doSomething();
}
}
you could instead do:
public void doSomethingWithOrders(Customer customer, Calendar from, Calendar to) {
List = orderService.getOrders(customer, from, to);
for (Order order : orders) {
order.doSomething();
}
}
This is 'looser' coupling, but still you can get all the orders belonging to a customer. I'm sure there's smarter people than me that have the right names and links referring to the above.
I believe that your problem is actually related to Bounded Contexts. For what I see, "dealing with passwords, order history, refunds, customer segmentation", each one of these can be a bounded context. Therefore, you might consider splitting your WebsiteUser into multiple entities, each one corresponding to a context. There may arise some duplication, but you gain focus on your domain and get rid off very large classes with multiple responsibilities.