who killed object oriented design?
DESCRIPTION
Presentation about Object Oriented Design common anti-patterns, bad habits and how to avoid them.TRANSCRIPT
![Page 1: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/1.jpg)
Who killedObject Oriented
Design?
![Page 2: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/2.jpg)
Colonel PHPwith a lead pipe in
the study?
![Page 3: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/3.jpg)
Just look around...
![Page 4: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/4.jpg)
Is OOD making programming more
enjoyable?
![Page 5: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/5.jpg)
How many abstract classes have you written lately?
![Page 6: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/6.jpg)
When was the last time that you had a
design meeting?
![Page 7: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/7.jpg)
Which one is your favorite LINQ expression?
![Page 8: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/8.jpg)
Why would you use yield or yield
return?
![Page 9: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/9.jpg)
Primitive Addiction
![Page 10: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/10.jpg)
Be lazy
![Page 11: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/11.jpg)
Make your life easier
![Page 12: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/12.jpg)
Avoid repetition
![Page 13: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/13.jpg)
Use the source Luke
![Page 14: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/14.jpg)
Creating dates is painful?
![Page 15: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/15.jpg)
DateTime.Parse("...")
![Page 16: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/16.jpg)
new DateTime(y, m, d)
![Page 17: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/17.jpg)
On.Jan(1)
On.Aug(3, 2013)
![Page 18: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/18.jpg)
Date arithmetic makes you crazy?
![Page 19: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/19.jpg)
DateTime.Today.AddDays(-3)
![Page 20: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/20.jpg)
3.Days().Ago
![Page 21: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/21.jpg)
5.Days().Span
![Page 22: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/22.jpg)
1.Month().Ago + 5.Days().Span
![Page 23: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/23.jpg)
On.Dec(10) - 2.Months().Span
![Page 24: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/24.jpg)
2.Months().Before(On.Dec(10))
![Page 25: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/25.jpg)
Date from and to in every method?
![Page 26: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/26.jpg)
What’s missing?
![Page 27: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/27.jpg)
Use a DateRange
![Page 28: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/28.jpg)
new DateRange(!!!!!!On.Jul(1),!!!!!!1.Month().Span)
![Page 29: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/29.jpg)
public class DateRange:!!!!!IEnumerable<DateTime>
![Page 30: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/30.jpg)
var r = new DateRange(!!!!!!!!!!!!!!On.Jul(1), !!!!!!!!!!!!!!On.Sep(3)) r.Select(d => ....)
![Page 31: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/31.jpg)
Generates a sequence of dates
![Page 32: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/32.jpg)
public IEnumerator<DateTime> GetEnumerator() { var counter = this.StartDate;
while (counter <= this.EndDate) { yield return counter; counter = counter.AddDays(1); } }
![Page 33: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/33.jpg)
Anemic models
![Page 34: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/34.jpg)
OO mixes behavior and data
![Page 35: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/35.jpg)
Models usually represent data
![Page 36: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/36.jpg)
...and you realize that there is hardly any behavior on these objects, making them little more than bags of getters and setters...
Martin Fowler
![Page 37: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/37.jpg)
Rich vs Anemic
![Page 38: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/38.jpg)
What about SOLID?
![Page 39: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/39.jpg)
Can we justify more classes?
![Page 40: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/40.jpg)
ValidatorsProcessorsRetrieversTranslators
ServicesBuilders
![Page 41: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/41.jpg)
class WorkingShift { public Code { get; set; } public Desc { get; set; }}
![Page 42: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/42.jpg)
Night, day or evening...Who’s responsible?
![Page 43: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/43.jpg)
shift.Code == "NIGHT"
![Page 44: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/44.jpg)
class WorkingShift { public Code { get; set; } public Desc { get; set; } public bool IsNight() { ... }}
![Page 45: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/45.jpg)
class Customer { public IsOfDrivingAge { get; } }
![Page 46: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/46.jpg)
How to decide?
![Page 47: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/47.jpg)
Functionality is Complex
![Page 48: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/48.jpg)
Functionality uses multiple models
![Page 49: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/49.jpg)
Interacting with external service
![Page 50: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/50.jpg)
Is not a core concern
![Page 51: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/51.jpg)
Multiple ways of implementation
![Page 52: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/52.jpg)
Some options
![Page 53: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/53.jpg)
Use extensions
![Page 54: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/54.jpg)
public static class CustomerExtensions{ public static bool ! ! ! ! IsOfDrivingAge(this Customer ...) }
![Page 55: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/55.jpg)
Decorator
![Page 56: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/56.jpg)
View Model
![Page 57: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/57.jpg)
Service Objects
![Page 58: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/58.jpg)
Form Objects
![Page 59: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/59.jpg)
Repository overpopulation
![Page 60: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/60.jpg)
Media tes be tween the domain and data mapping layers using a collection-like interface for accessing domain objects
Martin Fowler
![Page 61: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/61.jpg)
public interface IRepository<T>{ IEnumerable<T> All(); void Insert(T entity); void Delete(T entity);}
![Page 62: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/62.jpg)
Custom queries
![Page 63: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/63.jpg)
class CustomerRepository:! ! ! IRepository<Customer>{ // Implementation interface IEnumerable<Customer> FindByAddr(Address ) }
![Page 64: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/64.jpg)
CustomerRepositoryAddressRepositoryChairRepository
...
![Page 65: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/65.jpg)
IQueryable<T>
![Page 66: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/66.jpg)
public interface IRepository<T>{ IQueryable<T> All(); void Insert(T entity); void Delete(T entity);}
![Page 67: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/67.jpg)
class CustomerExtensions{ public IQueryable<Customer> FindByAddress( this IQueryable<Customer> query, Address address) { query.Where(c => c.Address == address) } }
![Page 68: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/68.jpg)
How many repositories?
![Page 69: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/69.jpg)
Only one generic implementation on top of your favorite ORM
![Page 70: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/70.jpg)
IOC container can instantiate the right one
![Page 71: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/71.jpg)
UnitOfWork can be a factory of
repositories
![Page 72: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/72.jpg)
Having an ORM do we really need a repository?
![Page 73: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/73.jpg)
Testing the testable test is
tested
![Page 74: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/74.jpg)
A test is about behavior
![Page 75: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/75.jpg)
Not implementation
![Page 76: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/76.jpg)
Writing expectations about implementation
makes it brittle
![Page 77: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/77.jpg)
public int ImportantMethod(){ var c1 = _dependency1.Calculate(); var c2 = _dependency2.Adjust(c1); return c2 + 10;}
![Page 78: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/78.jpg)
public void ImportantTest() { // arrange .... _dependency1! ! ! .Expect(d => d.Calculate())! ! ! .Once()! ! ! .AndReturn(50) _dependency2! ! ! .Expect(d => d.Adjust(50))! ! ! .Once()! ! ! .AndReturn(100) // act var actual = sut.ImportantMethod() // assert Assert.That(actual, Is.EqualTo(110))! VerifyAllExpectations()}
![Page 79: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/79.jpg)
public int ImportantMethod(){ var c1 = _dependency1.Calculate(); var c2 = _dependency2.Adjust(c1); return _dependency2.Adjust(c1) + 10;}
![Page 80: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/80.jpg)
public void ImportantTest() { // arrange .... _dependency1! ! ! ! .Stub(d => d.Calculate())! ! ! ! .AndReturn(50) _dependency2! ! ! ! .Stub(d => d.Adjust(50))! ! ! ! .AndReturn(100) // act var actual = sut.ImportantMethod() // assert Assert.That(actual, Is.EqualTo(110))}
![Page 81: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/81.jpg)
Abstraction subtraction
![Page 82: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/82.jpg)
Exercise in groups
![Page 83: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/83.jpg)
Hospital Domain Model
![Page 84: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/84.jpg)
Versions
![Page 85: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/85.jpg)
What the domain looked like
X months ago
![Page 86: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/86.jpg)
DB Driven Development
![Page 87: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/87.jpg)
Model may or may not match the database
![Page 88: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/88.jpg)
Active Record
![Page 89: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/89.jpg)
Transaction Script
![Page 90: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/90.jpg)
Data Mapper
![Page 91: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/91.jpg)
Coding is likeTelling a Story
![Page 92: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/92.jpg)
Leave the code cleaner than you found it
![Page 93: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/93.jpg)
Meaning is KING
![Page 94: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/94.jpg)
Don’t code what you don’t need
![Page 95: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/95.jpg)
Know your collections
![Page 96: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/96.jpg)
Let LINQ do the work for you
![Page 97: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/97.jpg)
Use extension methods to mimic a DSL
![Page 98: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/98.jpg)
Discuss design options
![Page 99: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/99.jpg)
Explore F#
![Page 100: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/100.jpg)
Thank you!
![Page 101: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/101.jpg)
The Smartest tool for lean project management
http://smartviewapp.com
![Page 103: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/103.jpg)
Photo Credit
• Under http://creativecommons.org/licenses/by/2.5/
• Joe Cheng, DSC_7820-01, http://flic.kr/p/2Zt2u
• Bill Ward, Derek Schin's Trucks 1, http://flic.kr/p/m5L5S
• Jeremy Keith, Roast beef, http://flic.kr/p/TKUz
• Rob Campbell, Field of daisies, http://flic.kr/p/6QJjU4
• Karin Dalziel, The Thinker, http://flic.kr/p/4UYArc
![Page 104: Who killed object oriented design?](https://reader034.vdocuments.net/reader034/viewer/2022042602/5594205d1a28ab37128b4693/html5/thumbnails/104.jpg)
Photo Credit 2• Under https://creativecommons.org/licenses/by-sa/2.0/
• Don LaVange, To Irene, https://flic.kr/p/49ihZX
• Under http://creativecommons.org/licenses/by-sa/3.0/us/
• Derick Bailey, SOLID Motivational Posters, http://bit.ly/17aVaHg
• MGA Roadster 1600 in Chariot Red: http://www.carandclassic.co.uk/car/C414652
• Cone of Uncertainty, http://www.agilenutshell.com/cone_of_uncertainty
• Burning Money, http://en.wikipedia.org/wiki/Money_burning#mediaviewer/File:Burning-money-and-yuanbao-at-the-cemetery-3249.JPG