making steaks from sacred cows

Post on 17-Jul-2015

333 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Making Steaks

from Sacred Cows

@KevlinHenney kevlin@curbralan.com

© BBC

I see Keep Out signs

as suggestions more

than actual orders.

Like Dry Clean Only.

Cargo cult programming is a style of computer programming characterized by the ritual inclusion of code or program structures that serve no real purpose.

Cargo cult programming can also refer to the results of applying a design pattern or coding style blindly without understanding the reasons behind that design principle.

http://en.wikipedia.org/wiki/Cargo_cult_programming

Une Idée

Rien n'est plus

dangereux qu'une

idée, quand on n'a

qu'une idée.

Émile-Auguste Chartier

Nothing is more

dangerous than an

idea, when you have

only one idea.

Émile-Auguste Chartier

Nothing is more

dangerous than an

IDE, when you have

only one IDE.

I currently have an average of 15-25 imports in each source file, which is seriously making my code mixed-up and confusing.

Is too many imports in your code a bad thing?

Is there any way around this?

http://stackoverflow.com/questions/8485689/too-many-imports-spamming-my-code

It's normal in Java world to have a lot of imports.

Not importing whole packages is good practice.

It's a good practice to import class by class instead of importing whole packages.

http://stackoverflow.com/questions/8485689/too-many-imports-spamming-my-code

Why?

It is not a problem. Any IDE will manage imports and show them to you only when needed.

Most IDEs support code folding where all the imports are folded down to one line. I rarely even see my imports these days as the IDE manages them and hides them as well.

Any good IDE, such as Eclipse, will collapse the imports in one line, and you can expand them when needed, so they won't clutter your view.

http://stackoverflow.com/questions/8485689/too-many-imports-spamming-my-code

It is not a problem. Any IDE will manage imports and show them to you only when needed.

Most IDEs support code folding where all the imports are folded down to one line. I rarely even see my imports these days as the IDE manages them and hides them as well.

Any good IDE, such as Eclipse, will collapse the imports in one line, and you can expand them when needed, so they won't clutter your view.

http://stackoverflow.com/questions/8485689/too-many-imports-spamming-my-code

It is not a problem. Any IDE will manage imports and show them to you only when needed.

Most IDEs support code folding where all the imports are folded down to one line. I rarely even see my imports these days as the IDE manages them and hides them as well.

Any good IDE, such as Eclipse, will collapse the imports in one line, and you can expand them when needed, so they won't clutter your view.

http://stackoverflow.com/questions/8485689/too-many-imports-spamming-my-code

What is the Matrix?

Control.

The Matrix is a computer-generated

dream world built to keep us under

control in order to change a human

being into this.

© Warner Bros.

I currently have an average of 15-25 imports in each source file, which is seriously making my code mixed-up and confusing.

Yes?

Is too many imports in your code a bad thing?

Yes.

Is there any way around this?

Yes!

Avoid Long Import Lists by Using Wildcards

Long lists of imports are daunting to the reader.

We don't want to clutter up the tops of our

modules with 80 lines of imports. Rather we

want the imports to be a concise statement

about which packages we collaborate with.

import java.util.ArrayList;

import java.util.Collection;

import java.util.HashMap;

import java.util.HashSet;

import java.util.LinkedHashMap;

import java.util.LinkedHashSet;

import java.util.LinkedList;

import java.util.List;

import java.util.Map;

import java.util.NavigableMap;

import java.util.NavigableSet;

import java.util.Set;

import java.util.SortedMap;

import java.util.SortedSet;

import java.util.TreeMap;

import java.util.TreeSet;

import java.util.*;

import java.beans.Introspector;

import java.lang.reflect.Array;

import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

import java.lang.reflect.Modifier;

import java.lang.reflect.Proxy;

import java.util.Arrays;

import java.util.Collection;

import java.util.Collections;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.LinkedHashSet;

import java.util.Map;

import java.util.Set;

import java.beans.*;

import java.lang.reflect.*;

import java.util.*;

import java.awt.*;

import java.util.*;

List?

import java.awt.*;

import java.util.*;

import java.util.List;

Open–Closed Principle

The principle stated that a good module

structure should be both open and closed:

Closed, because clients need the

module's services to proceed with their

own development, and once they have

settled on a version of the module should

not be affected by the introduction of new

services they do not need.

Open, because there is no guarantee that

we will include right from the start every

service potentially useful to some client.

[...] A good module structure

should be [...] closed [...] because

clients need the module's

services to proceed with their

own development, and once

they have settled on a version of

the module should not be

affected by the introduction of

new services they do not need.

Published Interface is a term I used (first in Refactoring) to refer to a class interface that's used outside the code base that it's defined in.

Martin Fowler http://martinfowler.com/bliki/PublishedInterface.html

There is no problem changing a

method name if you have access to

all the code that calls that method.

Even if the method is public, as long

as you can reach and change all the

callers, you can rename the method.

There is a problem only if the

interface is being used by code that

you cannot find and change. When

this happens, I say that the interface

becomes a published interface (a

step beyond a public interface).

Published Interface is a term I used (first in Refactoring) to refer to a class interface that's used outside the code base that it's defined in.

The distinction between published and public is actually more important than that between public and private.

The reason is that with a non-published interface you can change it and update the calling code since it is all within a single code base. [...] But anything published so you can't reach the calling code needs more complicated treatment.

Martin Fowler http://martinfowler.com/bliki/PublishedInterface.html

[...] A good module structure

should be [...] open [...] because

there is no guarantee that we will

include right from the start every

service potentially useful to some

client.

extends

A myth in the object-oriented design

community goes something like this:

If you use object-oriented technology,

you can take any class someone else

wrote, and, by using it as a base class,

refine it to do a similar task.

Robert B Murray

C++ Strategies and Tactics

Design and implement for

inheritance or else prohibit it

By now, it should be apparent that

designing a class for inheritance places

substantial limitations on the class.

Bertrand Meyer gave us guidance as long ago as 1988 when he coined the now famous open-closed principle. To paraphrase him:

Software entites (classes, modules, functions, etc.) should be open for extension, but closed for modification.

Robert C Martin "The Open-Closed Principle"

C++ Report, January 1996

http://blog.8thlight.com/uncle-bob/2014/05/12/TheOpenClosedPrinciple.html

http://blog.8thlight.com/uncle-bob/2014/05/12/TheOpenClosedPrinciple.html

I've heard it said that the OCP is wrong, unworkable, impractical, and not for real programmers with real work to do. The rise of plugin architectures makes it plain that these views are utter nonsense. On the contrary, a strong plugin architecture is likely to be the most important aspect of future software systems.

public abstract class Shape

{

...

}

public class Square : Shape

{

...

public void DrawSquare() ...

}

public class Circle : Shape

{

...

public void DrawCircle() ...

}

public abstract class Shape ...

public class Square : Shape ...

public class Circle : Shape ...

static void DrawAllShapes(Shape[] list)

{

foreach(Shape s in list)

if(s is Square)

(s as Square).DrawSquare();

else if(s is Circle)

(s as Circle).DrawCircle();

}

public abstract class Shape ...

public class Square : Shape ...

public class Circle : Shape ...

static void DrawAllShapes(Shape[] list)

{

foreach(Shape s in list)

if(s is Square)

(s as Square).DrawSquare();

else if(s is Circle)

(s as Circle).DrawCircle();

}

public abstract class Shape

{

...

public abstract void Draw();

}

public class Square : Shape

{

...

public override void Draw() ...

}

public class Circle : Shape

{

...

public override void Draw() ...

}

public abstract class Shape ...

public class Square : Shape ...

public class Circle : Shape ...

static void DrawAllShapes(Shape[] list)

{

foreach(Shape s in list)

s.Draw();

}

public abstract class Shape ...

public class Square : Shape ...

public class Circle : Shape ...

static void DrawAllShapes(Shape[] list)

{

foreach(Shape s in list)

s.Draw();

}

public abstract class Shape ...

public class Square : Shape ...

public class Circle : Shape ...

static void DrawAllShapes(Shape[] list)

{

foreach(Shape s in list)

s.Draw();

}

Bertrand Meyer gave us guidance as long ago as 1988 when he coined the now famous open-closed principle. To paraphrase him:

Software entites (classes, modules, functions, etc.) should be open for extension, but closed for modification.

Robert C Martin "The Open-Closed Principle"

C++ Report, January 1996

Bertrand Meyer gave us guidance as long ago as 1988 when he coined the now famous open-closed principle. To paraphrase him:

Software entites (classes, modules, functions, etc.) should be open for extension, but closed for modification.

Robert C Martin "The Open-Closed Principle"

C++ Report, January 1996

This double requirement looks like a

dilemma, and classical module

structures offer no clue.

This double requirement looks like a

dilemma, and classical module

structures offer no clue. But

inheritance solves it.

This double requirement looks like a

dilemma, and classical module

structures offer no clue. But

inheritance solves it. A class is

closed, since it may be compiled,

stored in a library, baselined, and

used by client classes. But it is also

open, since any new class may use

it as parent, adding new features.

public abstract class Shape ...

public class Square : Shape ...

public class Circle : Shape ...

static void DrawAllShapes(Shape[] list)

{

foreach(Shape s in list)

if(s is Square)

(s as Square).DrawSquare();

else if(s is Circle)

(s as Circle).DrawCircle();

}

public abstract class Shape ...

public class Square : Shape ...

public class Circle : Shape ...

static void DrawAllShapes(Shape[] list)

{

foreach(Shape s in list)

if(s is Square)

(s as Square).DrawSquare();

else if(s is Circle)

(s as Circle).DrawCircle();

}

public abstract class Shape ...

public class Square : Shape ...

public class Circle : Shape ...

static void DrawAllShapes(Shape[] list)

{

foreach(Shape s in list)

s.Draw();

}

public abstract class Shape ...

public class Square : Shape ...

public class Circle : Shape ...

static void DrawAllShapes(Shape[] list)

{

foreach(Shape s in list)

s.Draw();

}

Don't publish

interfaces prematurely.

Modify your code

ownership policies to

smooth refactoring.

Constructors that throw

Do not throw from a constructor.

Do not throw from a constructor?

Immutable Value

The internal state of a value

object is set at construction

and no subsequent

modifications are allowed.

To some, the most important

aspect of exceptions is that they

provide a general mechanism for

reporting errors detected in a

constructor.

Bjarne Stroustrup

The Design and Evolution of C++

Naomi Epel The Observation Deck

Exceptional Naming

ClassNotFoundException

EnumConstantNotPresentException

IllegalArgumentException

IllegalAccessException

IndexOutOfBoundsException

NegativeArraySizeException

NoSuchMethodException

TypeNotPresentException

UnsupportedOperationException

ClassNotFound

EnumConstantNotPresent

IllegalArgument

IllegalAccess

IndexOutOfBounds

NegativeArraySize

NoSuchMethod

TypeNotPresent

UnsupportedOperation

ArithmeticException

ArrayStoreException

ClassCastException

InstantiationException

NullPointerException

SecurityException

Arithmetic

ArrayStore

ClassCast

Instantiation

NullPointer

Security

IntegerDivisionByZero

IllegalArrayElementType

CastToNonSubclass

ClassCannotBeInstantiated

NullDereferenced

SecurityViolation

Omit needless words.

William Strunk and E B White

The Elements of Style

Shoulda Woulda Coulda

public static bool IsLeapYear(int year) ...

[Test] public void TestIsLeapYear() ...

function test

test

test

method test

test

test

method

method

test

test

YearsNotDivisibleBy4...

YearsDivisibleBy4ButNotBy100...

YearsDivisibleBy100ButNotBy400...

YearsDivisibleBy400...

Years_not_divisible_by_4_...

Years_divisible_by_4_but_not_by_100_...

Years_divisible_by_100_but_not_by_400_...

Years_divisible_by_400_...

Years_not_divisible_by_4_should_not_be_leap_years

Years_divisible_by_4_but_not_by_100_should_be_leap_years

Years_divisible_by_100_but_not_by_400_should_not_be_leap_years

Years_divisible_by_400_should_be_leap_years

Years_not_divisible_by_4_are_not_leap_years

Years_divisible_by_4_but_not_by_100_are_leap_years

Years_divisible_by_100_but_not_by_400_are_not_leap_years

Years_divisible_by_400_are_not_leap_years

Years_not_divisible_by_4_are_not_leap_years

Years_divisible_by_4_but_not_by_100_are_leap_years

Years_divisible_by_100_but_not_by_400_are_not_leap_years

Years_divisible_by_400_are_not_leap_years

Years_not_divisible_by_4_are_not_leap_years

Years_divisible_by_4_but_not_by_100_are_leap_years

Years_divisible_by_100_but_not_by_400_are_not_leap_years

Years_divisible_by_400_are_not_leap_years

Propositions are vehicles for stating how things are or might be.

Thus only indicative sentences which it makes sense to think of as being true or as being false are capable of expressing propositions.

Make definite assertions. Avoid tame, colourless, hesitating, noncommittal language.

Note [...] that when a sentence is made stronger, it usually becomes shorter. Thus brevity is a by-product of vigour.

William Strunk and E B White

The Elements of Style

top related