Working with others
- Avoid :
- missing code files
- ugly code naming
- code deletion
- Anticipate problems
- Rules are required
- Coding style
- Code reviewal
- Automated process
Software Craftmanship Basics
- Quality : clean code, refactoring, tests, simple design
- Humility : question yourself, countinously improvement
- Sharing : pair programming, collective ownership of source code
- Pragmatism : understand constraint, adapt !
- Professionalism : treat your client as a partner
Design patterns
What is a design pattern ?
A general, reusable solution to a commonly occurring problem within a given context in software design.
GoF : 24 patterns
- Creational
- Builder, Factory Method, Abstract factory, Prototype, Singleton
- Structural
- Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy, Delegation
- Behavioral
- Chain of responsability, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template method, Visitor
Design patterns Creational
The singleton
Restricts the instanciation of a class to one object.
Singleton |
---|
- Singleton : Singleton |
- Singleton() + getInstance() : Singleton |
public class Singleton {
private static readonly Singleton instance = new Singleton();
private Singleton() { }
public static Singleton Instance() {
return instance;
}
}
This is a thread-safe implementation.
Factory method
Creating objects without having to specify the exact class of the object that will be created.
interface IFruit {
int Price { get; }
}
class Cherry : IFruit {
public int Price { get; } = 75;
}
class Apple : IFruit {
public int Price { get; } = 100;
}
class Banana : IFruit {
public int Price { get; } = 150;
}
enum FruitType {
Banana,
Apple,
Cherry
}
class FruitFactory {
private Dictionary<FruitType, Func<IFruit>> mapper;
public FruitFactory() {
mapper = new Dictionary<FruitType, Func<IFruit>> {
{FruitType.Apple, () => new Apple()},
{FruitType.Banana, () => new Banana()},
{FruitType.Cherry, () => new Cherry()}
};
}
public IFruit Create(FruitType type) {
if (!mapper.TryGetValue(type, out var result)) {
throw new Exception("No fruit with type {type}");
}
return result();
}
}
Design Patterns Structural
Adapter (aka Wrapper)
Allows the interface of an existing class to be used as another interface.
interface IOAdapter {
String Read();
void Write(String message);
}
class ConsoleAdapter : IOAdapter {
public String Read() {
return Console.Readline();
}
public void Write(String message) {
Console.WriteLine(message);
}
}
Decorator
Allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.
public interface IBananaDecorator : IFruit {
Banana Banana { get; }
}
public class HandOfBanana : IBananaDecorator {
const int factor = 4;
public HandOfBanana(Banana banana)
{
Banana = banana;
}
public int Price => Banana.Price * factor;
public Banana Banana { get; }
public int Accept(IFruitVisitor fruitVisitor)
{
return Banana.Accept
(fruitVisitor) * factor;
}
}
Design Patterns Behavioural
Visitor
A way of separating an algorithm from an object structure on which it operates.
public interface IFruit {
int Price { get; }
int Accept(IFruitVisitor fruitVisitor);
}
public class Cherry : IFruit {
public int Price { get; } = 75;
public int Accept(IFruitVisitor fruitVisitor) {
return fruitVisitor.Apply(this);
}
}
public interface IFruitVisitor {
int Apply(Cherry fruit);
int Apply(Banana fruit);
int Apply(Apple fruit);
}
internal class CherryPromotion : IFruitVisitor {
private int count;
public int Apply(Apple fruit) {
return fruit.Price;
}
public int Apply(Banana fruit) {
return fruit.Price;
}
public int Apply(Cherry fruit) {
var reduction = 0;
count++;
if (count % 2 == 0) {
reduction = -20;
}
return fruit.Price + reduction;
}
}
Observer
An object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
public interface IObservableBasket
{
void Register(IBasketObserver observer);
void Add(IFruit fruit);
}
public class ObservableBasket : IObservableBasket
{
List<IFruit> list = new List<IFruit>();
private readonly List<IBasketObserver> observers = ...
public void Register(IBasketObserver observer) {
observers.Add(observer);
}
public void Add(IFruit fruit) {
list.Add(fruit);
Notify(fruit);
}
private void Notify(IFruit fruit) {
foreach (var observer in observers) {
observer.Notify(fruit);
}
}
}
public interface IBasketObserver
{
void Notify(IFruit fruit);
}
class BasketLogger : IBasketObserver
{
public void Notify(IFruit fruit)
{
ConsoleAdapter.Instance.Write($"Item added : “
+ fruit.GetType().Name);
}
}
Strategy
Enables selecting an algorithm at runtime.
public class CherryForStrategy : Cherry
{
public CherryForStrategy(IPriceStrategy strategy)
{
Strategy = strategy;
}
public IPriceStrategy Strategy { get; set; }
public override int Price => Strategy.Apply(base.Price);
}
public interface IPriceStrategy
{
int Apply(int defaultPrice);
}
public class SecondAtHalfPrice : IPriceStrategy
{
private int count;
public int Apply(int defaultPrice)
{
var reduction = 0;
count++;
if (count % 2 == 0)
{
reduction = -20;
}
return defaultPrice + reduction;
}
}
Organize your time
Get Things Done
- Capture / collect
- Clarify / process
- Organize
- Reflect / plan
- Engage / do
Pomodoro
- Focus on one task during 25 min
- Take a break 5 min
- Repeat 3 or 4 times
- Take a break 20 min
Eisenhower matrix
Organize your code
Version control system
VCS | Revision | Mode |
---|---|---|
CVS | Per file | Client-server |
SVN | Per commit | Client-server |
GIT | Per commit | Distributed |
Branching modes
- How many productions versions ?
- How many developers ?
- Which development process ?
Feature
Release
Organize your learning
Train yourself
- Monitory technology
- Try them : POC
- Be careful of the silver bullet syndrome
Train with others
- Coding dojo / Kata
- Pair programming
- Code reviews