Top Banner
Applying functional programming approaches in object oriented languages Mark Needham © ThoughtWorks 2010
150

Mixing functional programming approaches in an object oriented language

Aug 26, 2014

Download

Technology

Mark Needham

My slides from Biz Tech Delhi
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Mixing functional programming approaches in an object oriented language

Applying functional programming approaches in object oriented languages

Mark Needham

© ThoughtWorks 2010

Page 2: Mixing functional programming approaches in an object oriented language

C# 1.0

Page 3: Mixing functional programming approaches in an object oriented language

int[] ints = new int[] {1, 2, 3, 4, 5}

 

Page 4: Mixing functional programming approaches in an object oriented language

int[] Filter(int[] ints){    ArrayList results = new ArrayList();

    foreach (int i in ints)    {

if (i % 2 == 0) {

results.Add(i); }

    }

    return results.ToArray(typeof(int));}

Page 5: Mixing functional programming approaches in an object oriented language

int[] ints = new int[] {1, 2, 3, 4, 5}

 

Page 6: Mixing functional programming approaches in an object oriented language

int[] Filter(int[] ints){    ArrayList results = new ArrayList();

    foreach (int i in ints)    {

if (i > 3 == 0){

results.Add(i);}

    }

    return results.ToArray(typeof(int));}

Page 7: Mixing functional programming approaches in an object oriented language

int[] Filter(int[] ints){    ArrayList results = new ArrayList();

    foreach (int i in ints)    {

if (i % 2 == 0){

results.Add(i);}

    }

    return results.ToArray(typeof(int));}

Page 8: Mixing functional programming approaches in an object oriented language

int[] Filter(int[] ints){    ArrayList results = new ArrayList();

    foreach (int i in ints)    {

if (i >3 == 0){

results.Add(i);}

    }

    return results.ToArray(typeof(int));}

Page 9: Mixing functional programming approaches in an object oriented language

interface IIntegerPredicate{

bool Matches(int value);}

Page 10: Mixing functional programming approaches in an object oriented language

class EvenPredicate : IIntegerPredicate{

bool Matches(int value){

return value % 2 == 0;}

}

Page 11: Mixing functional programming approaches in an object oriented language

class GreaterThan3Predicate : IIntegerPredicate{

bool Matches(int value){

return value > 3;}

}

Page 12: Mixing functional programming approaches in an object oriented language

int[] Filter(int[] ints, IIntegerPredicate predicate){    ArrayList results = new ArrayList();

    foreach (int i in ints)    {

if (predicate.Matches(i)){

results.Add(i);}

    }

    return results.ToArray(typeof(int));}

Page 13: Mixing functional programming approaches in an object oriented language

int[] ints = new int[] {1, 2, 3, 4, 5 };

int[] even = Filter(ints, new EvenPredicate());

int[] greaterThan3 = Filter(ints, new GreaterThan3Predicate());

Page 14: Mixing functional programming approaches in an object oriented language

interface IIntegerPredicate{

bool Matches(int value);}

Page 15: Mixing functional programming approaches in an object oriented language

bool delegate IntegerPredicate(int value);

Page 16: Mixing functional programming approaches in an object oriented language

bool Even(int value){

return value % 2 == 0;}

Page 17: Mixing functional programming approaches in an object oriented language

bool GreaterThan3(int value){

return value > 3;}

Page 18: Mixing functional programming approaches in an object oriented language

int[] Filter(int[] ints, IntegerPredicate predicate){    ArrayList results = new ArrayList();

    foreach (int i in ints)    {                

if (predicate(i)) {

results.Add(i); }

    }

    return results.ToArray(typeof(int));}

Page 19: Mixing functional programming approaches in an object oriented language

int[] ints = new int[] {1, 2, 3, 4, 5 };

int[] even = Filter(ints, new IntegerPredicate(Even));

int[] greaterThan3 = Filter(ints,  new

IntegerPredicate(GreaterThan3));

Page 20: Mixing functional programming approaches in an object oriented language

C# 2.0

 

Page 21: Mixing functional programming approaches in an object oriented language

Inference

int[] ints = new int[] {1, 2, 3, 4, 5 };

int[] even = Filter(ints, new IntegerPredicate(Even));

int[] greaterThan3 = Filter(ints, new IntegerPredicate(GreaterThan3));

Page 22: Mixing functional programming approaches in an object oriented language

Inference

int[] ints = new int[] {1, 2, 3, 4, 5 };

int[] even = Filter(ints, Even);

int[] greaterThan3 = Filter(ints, GreaterThan3);

Page 23: Mixing functional programming approaches in an object oriented language

Generics

delegate bool IntegerPredicate(int value);

Page 24: Mixing functional programming approaches in an object oriented language

Generics

delegate bool Predicate<T> (T value);

Page 25: Mixing functional programming approaches in an object oriented language

Generics

int[] Filter(int[] ints, IntegerPredicate predicate){

ArrayList results = new ArrayList();

foreach (int i in ints){

if (predicate(i)){

results.Add(i);}

}

return results.ToArray(typeof(int));}

Page 26: Mixing functional programming approaches in an object oriented language

Generics

T[] Filter<T>(T[] values, Predicate<T> predicate){

List<T> results = new List<T>();

foreach (T i in value){

if (predicate(i)){

results.Add(i);}

}

return results.ToArray();}

Page 27: Mixing functional programming approaches in an object oriented language

Iterators

IEnumerable<T> Filter<T>(IEnumerable<T> values, Predicate<T> p)

{List<T> results = new List<T>();

foreach (T i in value){

if (p(i)){

results.Add(i);}

}

return results;}

Page 28: Mixing functional programming approaches in an object oriented language

Iterators

IEnumerable<T> Filter<T>(IEnumerable<T> values, Predicate<T> p)

{foreach (T i in value){

if (p(i)){

yield return i;}

}}

Page 29: Mixing functional programming approaches in an object oriented language

Anonymous Methods

IEnumerable<int> greaterThan3 = Filter(ints, GreaterThan3);

Page 30: Mixing functional programming approaches in an object oriented language

Anonymous Methods

IEnumerable<int> greaterThan3 = Filter(ints, delegate(int value) { return value > 3; });

Page 31: Mixing functional programming approaches in an object oriented language

Anonymous Methods

int minimumValue = 3;

IEnumerable<int> greaterThan3 = Filter(ints, delegate(int value) { return value > minimumValue; });

Page 32: Mixing functional programming approaches in an object oriented language

C# 3.0

 

Page 33: Mixing functional programming approaches in an object oriented language

Lambdas

int minimumValue = 3;

IEnumerable<int> greaterThan3 = Filter(ints, delegate(int value) { return value > minimumValue; });

Page 34: Mixing functional programming approaches in an object oriented language

Lambdas

int minimumValue = 3;

IEnumerable<int> greaterThan3 = Filter(ints, value => value > minimumValue);

Page 35: Mixing functional programming approaches in an object oriented language

More Type Inference

int minimumValue = 3;

IEnumerable<int> greaterThan3 = Filter(ints, value => value > minimumValue);

Page 36: Mixing functional programming approaches in an object oriented language

More Type Inference

int minimumValue = 3;

var greaterThan3 = Filter(ints, value => value > minimumValue);

Page 37: Mixing functional programming approaches in an object oriented language

Extension Methods

int minimumValue = 3;

var greaterThan3 = Filter(ints, value => value > minimumValue);

Page 38: Mixing functional programming approaches in an object oriented language

Extension Methods

int minimumValue = 3;

var greaterThan3 = ints.Filter(value => value > minimumValue);

Page 39: Mixing functional programming approaches in an object oriented language

LINQ

Page 40: Mixing functional programming approaches in an object oriented language

LINQ

New delegates in System namespaceAction<T>, Action<T1, T2>, Func<TResult>, Func<T1, TResult> etc.

Page 41: Mixing functional programming approaches in an object oriented language

LINQ

New delegates in System namespaceAction<T>, Action<T1, T2>, Func<TResult>, Func<T1, TResult> etc.

System.LinqExtension methods Where, Select, OrderBy etc.

Page 42: Mixing functional programming approaches in an object oriented language

LINQ

New delegates in System namespaceAction<T>, Action<T1, T2>, Func<TResult>, Func<T1, TResult> etc.

System.LinqExtension methods Where, Select, OrderBy etc. Some compiler magic to translate sql style code to method calls

Page 43: Mixing functional programming approaches in an object oriented language

LINQ

var even = ints.Where(value => value % 2 == 0) var greaterThan3 = ints.Where(value => value > 3) or

var even = from value in ints                  where value % 2 == 0                  select value  var greaterThan3 = from value in ints                                       where value > 3                                                   select value                                      

Page 44: Mixing functional programming approaches in an object oriented language

Interfaces

Delegates

Anonymous methods

Lambdas

Page 45: Mixing functional programming approaches in an object oriented language

So this functional programming thing…

Page 46: Mixing functional programming approaches in an object oriented language

http://www.flickr.com/photos/stuartpilbrow/2938100285/sizes/l/

Page 47: Mixing functional programming approaches in an object oriented language

Higher order functions

Page 48: Mixing functional programming approaches in an object oriented language

var ints = new int[] {1, 2, 3, 4, 5 };

var greaterThan3 = ints.Where(value => value > 3)

var even = ints.Where(value => value % 2 == 0)

Page 49: Mixing functional programming approaches in an object oriented language

Pure functions

Page 50: Mixing functional programming approaches in an object oriented language

Immutability

Page 51: Mixing functional programming approaches in an object oriented language

Lazy evaluation

Page 52: Mixing functional programming approaches in an object oriented language

Iterators

IEnumerable<T> Filter<T>(IEnumerable<T> values, Predicate<T> p)

{foreach (T i in value){

if (p(i)){

yield return i;}

}}

Page 53: Mixing functional programming approaches in an object oriented language

Recursion & Pattern Matching

Page 54: Mixing functional programming approaches in an object oriented language

Transformational Mindset

We can just pass functions around instead in most cases- find an example where it still makes sense to use the GOF approach though.

Page 55: Mixing functional programming approaches in an object oriented language

Input -> ??? -> ??? -> ??? -> Output

Page 56: Mixing functional programming approaches in an object oriented language

http://www.emt-india.net/process/petrochemical/img/pp4.jpg

Page 57: Mixing functional programming approaches in an object oriented language

So why should you care?

Page 58: Mixing functional programming approaches in an object oriented language

Functional can fill in the gaps in OO code

 

Page 59: Mixing functional programming approaches in an object oriented language

Programming in the…

LargeMedium

Small

Page 60: Mixing functional programming approaches in an object oriented language

Programming in the …

LargeMedium

Small

“a high level that affects as well as crosscuts multiple classes and functions”

Page 61: Mixing functional programming approaches in an object oriented language

Programming in the …

LargeMedium

Small

“a single API or group of related APIs in such things as classes, interfaces, modules”

Page 62: Mixing functional programming approaches in an object oriented language

Programming in the …

LargeMedium

Small

“individual function/method bodies”

Page 63: Mixing functional programming approaches in an object oriented language

LargeMedium

Small

Page 64: Mixing functional programming approaches in an object oriented language

LargeMedium

Small

Page 65: Mixing functional programming approaches in an object oriented language

Abstractions over common operations means less code and less chances to make mistakes

Page 66: Mixing functional programming approaches in an object oriented language

Projection

Page 67: Mixing functional programming approaches in an object oriented language

 

  

 people.Select(person => person.Name)  

Page 68: Mixing functional programming approaches in an object oriented language

 

  

people.SelectMany(person => person.Pets)

Page 69: Mixing functional programming approaches in an object oriented language

Restriction

 

Page 70: Mixing functional programming approaches in an object oriented language

 

         

            people.Where(person => person.HasPets) 

Page 71: Mixing functional programming approaches in an object oriented language

Partitioning

 

Page 72: Mixing functional programming approaches in an object oriented language

 

  

people.Take(5)

Page 73: Mixing functional programming approaches in an object oriented language

 

  

people.Skip(5)

Page 74: Mixing functional programming approaches in an object oriented language

 

  

            people.TakeWhile(person =>                             person.Name != "David")

Page 75: Mixing functional programming approaches in an object oriented language

 

              people.SkipWhile(person =>                                 person.Name != "David")

Page 76: Mixing functional programming approaches in an object oriented language

Set

 

Page 77: Mixing functional programming approaches in an object oriented language

 

people.Select(person => person.Name).Distinct()

Page 78: Mixing functional programming approaches in an object oriented language

 

 people.Union(someOtherPeople) 

Page 79: Mixing functional programming approaches in an object oriented language

 

  

people.Intersect(someOtherPeople)

Page 80: Mixing functional programming approaches in an object oriented language

 

  

people.Except(someOtherPeople)

Page 81: Mixing functional programming approaches in an object oriented language

Ordering and Grouping

 

Page 82: Mixing functional programming approaches in an object oriented language

 

  

people.OrderBy(person => person.Name)  

Page 83: Mixing functional programming approaches in an object oriented language

 

  

people.GroupBy(person => person.Name)

Page 84: Mixing functional programming approaches in an object oriented language

Aggregation

 

Page 85: Mixing functional programming approaches in an object oriented language

 

  

people.Count()

Page 86: Mixing functional programming approaches in an object oriented language

 

  

people.Select(person => person.Age).Sum()

Page 87: Mixing functional programming approaches in an object oriented language

 

  

people.Select(person => person.Age).Min()

Page 88: Mixing functional programming approaches in an object oriented language

 

  

people.Select(person => person.Age).Max()

Page 89: Mixing functional programming approaches in an object oriented language

 

  

people.Select(person => person.Age).Average()

Page 90: Mixing functional programming approaches in an object oriented language

 

  

       people.Select(person => person.Age)            .Aggregate(0, (totalAge, nextAge) =>                     nextAge % 2 == 0                         ? nextAge + totalAge                         : totalAge)

Page 91: Mixing functional programming approaches in an object oriented language

Joining

 

Page 92: Mixing functional programming approaches in an object oriented language

 

          people.Join(addresses,                           person => person.PersonId,                  address => address.PersonId,                     (person, address) => new {                                         person, address})

Page 93: Mixing functional programming approaches in an object oriented language

Embrace the collection

 

Page 94: Mixing functional programming approaches in an object oriented language

 var first = “Mark”;var middle = “Harold”;var surname = “Needham”;

var fullname = first + “ “ + middle + “ “ + surname;

or

var names = new[] {first, middle, surname};var fullname = String.Join(“ “, names);

Page 95: Mixing functional programming approaches in an object oriented language

 public class SomeObject{ public SomeObject(string p1, string p2, string p3) { if(p1 == null) throw new Exception(…); if(p2 == null) throw new Exception(…); if(p3 == null) throw new Exception(…);

// rest of constructor logic }}

Page 96: Mixing functional programming approaches in an object oriented language

 public class SomeObject{ public SomeObject(string p1, string p2, string p3) { var parameters = new[] {p1, p2, p3}; if(parameters.Any(p => p = null) throw new Exception(…).

// rest of constructor logic }}

Page 97: Mixing functional programming approaches in an object oriented language

LargeMedium

Small

Page 98: Mixing functional programming approaches in an object oriented language

We can just pass functions around instead in most cases- find an example where it still makes sense to use the GOF approach though.

Page 99: Mixing functional programming approaches in an object oriented language
Page 100: Mixing functional programming approaches in an object oriented language

 

 

public class SomeObject{

private readonly IStrategy strategy;

public SomeObject(IStrategy strategy){

this.strategy = strategy;}

public void DoSomething(string value){

strategy.DoSomething(value);}

}

Page 101: Mixing functional programming approaches in an object oriented language

 

 public class Strategy : IStrategy{

public void DoSomething(string value){

// do something with string}

}

Page 102: Mixing functional programming approaches in an object oriented language

 

 

public class SomeObject{

private readonly Action<string> strategy;

public SomeObject(Action<string> strategy){

this.strategy = strategy;}

public void DoSomething(string value){

strategy(value);}

}

Page 103: Mixing functional programming approaches in an object oriented language

 

Hole in the middle pattern

Page 104: Mixing functional programming approaches in an object oriented language

 

 

public class ServiceCache<Service>{ protected Res FromCacheOrService <Req, Res>(Func<Res> serviceCall, Req request) { var cachedRes = cache.RetrieveIfExists( typeof(Service), typeof(Res), request);

  if(cachedRes == null) { cachedRes = serviceCall(); cache.Add(typeof(Service), request, cachedRes); }

return (Res) cachedRes; }}

Page 105: Mixing functional programming approaches in an object oriented language

 

 public class CachedService : ServiceCache<IService>{

public MyResult GetMyResult(MyRequest request){

          return FromCacheOrService(()                  => service.GetMyResult(request), request);

}}

Page 106: Mixing functional programming approaches in an object oriented language

 

Maybe?

Page 107: Mixing functional programming approaches in an object oriented language

 

public interface Maybe<T>{

bool HasValue();T Value();

}

Page 108: Mixing functional programming approaches in an object oriented language

 

public class Some<T> : Maybe<T>{

private readonly T theThing;

public Some(T theThing){

this.theThing = theThing;}

public bool HasValue (){

return true;}

public T Value(){

return theThing;}

}

Page 109: Mixing functional programming approaches in an object oriented language

 public class None<T> : Maybe<T>{

public bool HasValue (){

return false;}

public T Value(){

throw new NotImplementedException();}

}

Page 110: Mixing functional programming approaches in an object oriented language

  public class Some{

public static Some<T> Thing<T>(T thing) : where T : class

{return new Some<T>(thing);

}}

Page 111: Mixing functional programming approaches in an object oriented language

 

public class No{

public static None<T> Thing<T>()

{return new None<T>();

}}

Page 112: Mixing functional programming approaches in an object oriented language

 

public static class MaybeExtensions{

public static Maybe<T> Maybify<T>(this T source)where T : class

{if(source == null)

return No.Thing<T>();

return Some.Thing(source);}

}

recordFromDatabase.Maybify():

Page 113: Mixing functional programming approaches in an object oriented language

 

public class FooService{

public Foo FindOrCreate(int fooId){

var foo = fooRepository.Find(fooId);

if(foo.HasValue()){

return foo.Value();}

return fooRepository.Create(fooId);}

}

Page 114: Mixing functional programming approaches in an object oriented language

 

Continuation Passing Style

Page 115: Mixing functional programming approaches in an object oriented language

 

static void Identity<T>(T value, Action<T> k) {

k(value); }

Page 116: Mixing functional programming approaches in an object oriented language

 

Identity("foo", s => Console.WriteLine(s));

Page 117: Mixing functional programming approaches in an object oriented language

 

Identity("foo", s => Console.WriteLine(s));

as compared to

var foo = Identity(“foo”);Console.WriteLine(foo);

Page 118: Mixing functional programming approaches in an object oriented language

 

public ActionResult Submit(string id, FormCollection form) {    var shoppingBasket = CreateShoppingBasketFrom(id, form);      return IsValid(shoppingBasket, ModelState,          () => RedirectToAction("index", "ShoppingBasket", new { shoppingBasket.Id} ),  

() => LoginUser(shoppingBasket,                  () =>                  {                    ModelState.AddModelError("Password", "User name/email address was incorrect - please re-enter");                      return RedirectToAction("index", ""ShoppingBasket",

new { Id = new Guid(id) });                 }, user =>                  {                    shoppingBasket.User = user;                      UpdateShoppingBasket(shoppingBasket);                      return RedirectToAction("index", "Purchase",   

new { Id = shoppingBasket.Id }); }         )); }

Page 119: Mixing functional programming approaches in an object oriented language

 

private RedirectToRouteResult IsValid(ShoppingBasket shoppingBasket,                                       ModelStateDictionary modelState,                                        Func<RedirectToRouteResult> failureFn,                     

Func<RedirectToRouteResult> successFn) {   return validator.IsValid(shoppingBasket, modelState) ? successFn() : failureFn(); }  

private RedirectToRouteResult LoginUser(ShoppingBasket shoppingBasket,                                                                  Func<RedirectToRouteResult> failureFn,                                                                Func<User,RedirectToRouteResult> successFn) {

User user = null; try {

user = userService.CreateAccountOrLogIn(shoppingBasket); }   catch (NoAccountException) {

return failureFn(); }   return successFn(user);

}

Page 120: Mixing functional programming approaches in an object oriented language

 

Passing functions around

Page 121: Mixing functional programming approaches in an object oriented language

 

private void AddErrorIf<T>(Expression<Func<T>> fn, ModelStateDictionary modelState,

Func<ModelStateDictionary, Func<T,string, string, bool>> checkFn)

{var fieldName = ((MemberExpression)fn.Body).Member.Name;var value = fn.Compile().Invoke();var validationMessage = validationMessages[fieldName]);

checkFn.Invoke(modelState)(value, fieldName, validationMessage);}

AddErrorIf(() => person.HasPets, modelState, m => (v, f, e) => m.AddErrorIfNotEqualTo(v,true, f, e));

AddErrorIf(() => person.HasChildren, modelState, m => (v, f, e) => m.AddErrorIfNull(v, f, e));

Page 122: Mixing functional programming approaches in an object oriented language

 

http://www.thegeekshowpodcast.com/home/mastashake/thegeekshowpodcast.com/wp-content/uploads/2009/07/wtf-cat.jpg

Page 123: Mixing functional programming approaches in an object oriented language

So what could possibly go wrong?

 

http://icanhascheezburger.files.wordpress.com/2009/06/funny-pictures-cat-does-not-think-plan-will-fail.jpg

Page 124: Mixing functional programming approaches in an object oriented language

Hard to diagnose errors

 

Page 125: Mixing functional programming approaches in an object oriented language

var people = new [] {

new Person { Id=1, Address = new Address { Road = "Ewloe Road" }},

new Person { Id=2},new Person { Id=3, Address =

new Address { Road = "London Road"}} };

people.Select(p => p.Address.Road); 

Page 126: Mixing functional programming approaches in an object oriented language

Null Reference Exception on line 23

Page 127: Mixing functional programming approaches in an object oriented language

http://www.flickr.com/photos/29599641@N04/3147972713/

Page 128: Mixing functional programming approaches in an object oriented language

public T Tap(T t, Action action) {    action();    return t;}

Page 129: Mixing functional programming approaches in an object oriented language

people    .Select(p => Tap(p, logger.debug(p.Id))    .Select(p => p.Address.Road); 

Page 130: Mixing functional programming approaches in an object oriented language

if we have side effects  then favour foreach construct

foreach(var item in items){        itemRepository.Save(item);}

Page 131: Mixing functional programming approaches in an object oriented language

rather than:

items.ToList().ForEach(item => itemRepository.Save(item));

Page 132: Mixing functional programming approaches in an object oriented language

Readability

 

Page 133: Mixing functional programming approaches in an object oriented language

Lazy evaluation can have unexpected consequences

 

Page 134: Mixing functional programming approaches in an object oriented language

 

        IEnumerable<string> ReadNamesFromFile()        {            using(var fileStream = new FileStream("names.txt",                                                         FileMode.Open))            using(var reader = new StreamReader(fileStream))            {                var nextLine = reader.ReadLine();                while(nextLine != null)                {                    yield return nextLine;                    nextLine = reader.ReadLine();                }            }        }

Page 135: Mixing functional programming approaches in an object oriented language

 

        IEnumerable<Person> GetPeople()        {            return ReadNamesFromFile()

.Select(name => new Person(name));        }

Page 136: Mixing functional programming approaches in an object oriented language

 

     IEnumerable<Person> people = GetPeople();         foreach (var person in people)     {         Console.WriteLine(person.Name);     }         Console.WriteLine("Total number of people: " +

people.Count());

Page 137: Mixing functional programming approaches in an object oriented language

Encapsulation is still important

 

Page 138: Mixing functional programming approaches in an object oriented language

public Money CalculateSomething(Func<Customer, DateTime, Money> calculation)

{// do some calculation

}

Page 139: Mixing functional programming approaches in an object oriented language

public delegate Money PremiumCalculation(Customer customer, DateTime renewalDate);

Page 140: Mixing functional programming approaches in an object oriented language

public Money CalculateSomething(PremiumCalculation calculation)

{// do some calculation

}

Page 141: Mixing functional programming approaches in an object oriented language

 

Total salary for a company company.Employees

.Select(employee => employee.Salary) .Sum()

This could lead to duplication

What if we add rules to the calculation?

Who should really have this responsibility?.Sum()

Page 142: Mixing functional programming approaches in an object oriented language

Linq isn't the problem here, it's where we have put it

 

Page 143: Mixing functional programming approaches in an object oriented language

Company naturally has the responsibility so encapsulate the logic here

Page 144: Mixing functional programming approaches in an object oriented language

class Company{    public int TotalSalary    {        get         {            return employees.Select(e =>e.Salary).Sum();         }     } }

Page 145: Mixing functional programming approaches in an object oriented language

Sometimes we need to go further

 

Page 146: Mixing functional programming approaches in an object oriented language

If both Company and Division have employees do we duplicate the logic for total salary?

Page 147: Mixing functional programming approaches in an object oriented language

IEnumerable<T> and List<T> make collections easy but sometimes it is still better to create a

class to represent a collection

Page 148: Mixing functional programming approaches in an object oriented language

 

class EmployeeCollection{    private List<Employee> employees;       public int TotalSalary    {        get        {            return employees.Select(e => e.Salary).Sum();         }    }}

Page 149: Mixing functional programming approaches in an object oriented language

In conclusion…

 

Page 150: Mixing functional programming approaches in an object oriented language

Mark [email protected]

© ThoughtWorks 2010