The document discusses the importance of solid software design principles, including the Single Responsibility Principle and the Open/Closed Principle, emphasizing that software should be adaptable to future changes and user needs. It highlights common issues associated with technical debt and anticipatory coding, advocating for practices such as the Boy Scouts Rule to improve code quality. Ultimately, the document encourages developers to be proactive in maintaining high standards in software design.
The primary valueof software is that it is soft.
That it is resilient in the face of inevitable change.
That it not only meets the users' requirements and solves their problems in the
present tense, but that it can be readily adapted to meet needs that will arrive
tomorrow, or the next day.
The Value of Code
The Code should do its job, solving a problem that the user has today.
The secondary value of software:
Single Responsibility Principle
Aclass should have one, and only one, reason to change.
Open Closed Principle
You should be able to extend a classes behavior, without modifying it.
Common Closure Principle
Classes that change together are packaged together.
18.
Single Responsibility Principle
Aclass should have one, and only one, reason to change.
Open Closed Principle
You should be able to extend a classes behavior, without modifying it.
Common Closure Principle
Classes that change together are packaged together.
19.
Why does softwarechanges?
A change is requested by the product owner through a user story.
A user story relates to a business capability of the software.
A user story is written in business language.
A change comes as a user story, for a business capability, and is written in
business language.
20.
Single Responsibility Principle
Aclass should have one, and only one, reason to change.
Open Closed Principle
You should be able to extend a classes behavior, without modifying it.
Common Closure Principle
Classes that change together are packaged together.
Single Responsibility Principle
privateString assemblyDirections() {
String directions = "You can go";
for (Direction to : Direction.values()) {
if (canMoveTo(to)) {
directions += " " + to;
}
}
directions += " from here.";
return directions;
}
private List<Direction> getAvailableDirections() {
List<Direction> directions = new ArrayList<>();
for (Direction to : Direction.values()) {
if (canMoveTo(to)) {
directions.add(to);
}
}
return directions;
}
private String describe(Direction[] directions) {
String str = "You can go";
for (int i=0; i<directions.length; i++) {
str += " " + directions[i];
}
str += " from here.";
return directionsStr;
}
25.
Single Responsibility Principle
publicclass ResponseBuilder {
public Document buildReponseForAccept(int dealId) {
//Create service response for Accept request.
//...
}
public Document buildReponseForReject(int dealId, String reason) {
//Create service response for Reject request.
//...
}
public Document buildReponseForUpdate(int dealId, DealDiff diff) {
//Create service response for Update request.
//...
}
public Document buildResponseForWithdraw(int dealId) {
//Create service response for Update request.
//...
}
}
26.
Single Responsibility Principle
publicclass Configuration {
//...
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public boolean startInMaximizedWindow() {
return port;
}
public Color getMainThemeColor() {
return mainThrmeColor;
}
}
public static class ConnectionFactory {
private final String host;
private final int port;
@Inject
public ConnectionFactory(@Config String host,
@Config int port) {
this.host = host;
this.port = port;
}
//...
}
27.
Breaking the SingleResponsibility Principle
Break unrelated code
Unrelated tests fail Unrelated functionality breaks
Blame is thrown around Clients panic and build mistrust
28.
Open Closed Principle
publicvoid checkout(Receipt receipt) {
Money total = receipt.getTotal();
Payment p = acceptCash(total);
receipt.addPayment(p);
}
public void checkout(Receipt receipt,
PaymentMethodType paymentMethodType) {
Money total = receipt.getTotal();
Payment p = null;
if (paymentMethodType == CASH) {
p = acceptCash(total);
} else if (paymentMethodType == CREDIT) {
p = acceptCredit(total);
} else {
// There's no way to reached this. I hope.
}
receipt.addPayment(p);
}
public void checkout(Receipt receipt,
PaymentMethod paymentMethod) {
Money total = receipt.getTotal();
Payment p = paymentMethod.acceptPayment(total);
receipt.addPayment(p);
}
29.
Open Closed Principle
publicvoid handleRequest(Request request) {
switch (request.getType()) {
case ACCEPT:
handleAccept(request);
break;
case REJECT:
handleReject(request);
break;
case WITHDRAW:
handleWithdraw(request);
break;
default:
// Hope to never get here.
break;
}
}
public void handleRequest(Request request) {
for (RequestHandler handler : requestHandlers) {
if (handler.accept(request)) {
handler.handle(request);
}
}
}
Interface Segregation Principle
JohnAPI: writeCode, playFootball, drinkBeerInterface
Clients
John
Unsupported methodsMatthew
Unsupported methods Adrian Mutu
Services
Luxoft Team Leader Unneeded methods
Football team capitanUnneeded methods Unneeded methods
BuddyUnneeded methods
32.
John API: writeCode,playFootball, drinkBeer
Interface Segregation Principle
John
Matthew
Adrian Mutu
Football team capitan
Luxoft Team Leader
Buddy
Interface
Clients
Services
FootballPlayerProgrammer BeerDrinker
Unsupported methods
Unsupported methods
Unneeded methods
Unneeded methods Unneeded methods
Unneeded methods
Designing with principles- New Project
Never anticipate
Programmers are not the best at anticipating business needs.
Code written in anticipation of a business need is code unused, not tested in real life, getting in
the way.
Anticipatory code create needless abstraction, needless complexity.
YAGN.
Act!
Change the design as soon as needed to respect the principles.
36.
Getting to adesign - Legacy Code
Do nothing because
Feeling not authorized or scared to change badly designed code.
The job is overwhelming: too much to understand, change and test.
Fix it all, now!
Take 3 months to make everything perfect.
1 extra month to test everything.
Make it 6 months.
Can’t be done.
The Boy Scouts Rule
When you need to touch existing code, leave it better than you found it.
Add 4 – 8 hours to the task estimate to clean the code and apply the design principles.
37.
Coping with depression
Acceptthat most code is rotten.
Do not write code that rots easily.
When asking for refactoring time, use non-personal, well educated arguments.
Expect people to agree with you when discussing code quality.
Ignoring design principles affects the company but, most important, it also affects you.
Be the best programmer you can be, regardless of the circumstances.