solid design principles applied in java

Post on 13-Apr-2017

564 Views

Category:

Software

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

www.luxoft.com

SOLID Design Principles

Ionuț Bilică

What is Software Design?

javac

Why Is Design Important?

$$$$$66666

$6

javac$

6

$$$$$66666

Martin Fowler’s Design Stamina Hypothesis

Attention to Design

Tim

e n

ee

de

d to

im

ple

me

nt u

se

r sto

ry

User Stories

good design

no design

The primary value of 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:

SOLID

Single Responsibility Principle

Open Closed Principle

Liskov Substitution Principle

Interface Segregation Principle

Dependency Inversion Principle

Design Patterns vs Design Principles

cleancoders.com

Single Responsibility Principle

A class 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

A class 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.

Why does software changes?

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.

Single Responsibility Principle

A class 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.

Packaging

by type by function

Packaging

by type by function

non cohesive cohesive

Package cohesion

Single Responsibility Principle

private String 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;

}

Single Responsibility Principlepublic class 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.

//...

}

}

Single Responsibility Principlepublic class 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;

@Injectpublic ConnectionFactory(@Config String host,

@Config int port) {this.host = host;this.port = port;

}

//...

}

Breaking the Single Responsibility Principle

Break unrelated code

Unrelated tests fail Unrelated functionality breaks

Blame is thrown around Clients panic and build mistrust

Open Closed Principlepublic void 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);

}

Open Closed Principle

public void 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);

}

}

}

Liskov Substitution Principle

Interface Segregation Principle

John API: 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

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

Dependency Inversion

Luxoft

Work Procedures

John MatthewAlex

Dependency Inversion

Luxoft

Work Procedures

John MatthewAlex

Programmer QA

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.

Getting to a design - 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.

Coping with depression

Accept that 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.

www.luxoft.com

Thank you

Ionuț Bilică

ionut.bilica@gmail.com

top related