Object Calisthenics Gabriel Heming.

Slides:



Advertisements
Similar presentations
Language Features for JDK7 Neal Gafter Joshua Bloch Google.
Advertisements

Conceitos Fundamentais de Orientação a Objetos. Grupo de Estudo de Java Joselito Seção 1.
C# Language Report By Trevor Adams. Language History Developed by Microsoft Developed by Microsoft Principal Software Architect Principal Software Architect.
1 Java Object Model Part 1. 2 Type Definition: set of values – a set of values and set of operations –a set of operations that can be applied to those.
XP and Refactoring David Talby. Development Methodologies The Software Crisis – 84% of software projects are not on time – 31% of software projects never.
The If/Else Statement, Boolean Flags, and Menus Page 180
{ Welcome to CAMDUG Dojo Day Thank you to our hosts, Granta Design (We’re hiring!) Sorry for the lack of internet.
Crossword Puzzle Solver Michael Keefe. Solver structure.
Java Language and SW Dev’t
Mason Vail.  A data type definition – “blueprint for objects”  Includes properties and/or methods ◦ “instance” data / methods – specific to one object.
The Java Programming Language
Java Quiz Bowl A fun review of the Java you should know from CMPT 201 If you don’t know the answers - this week is for you to study up!
ACO 101: Introduction to Computer Science Anatomy Part 2: Methods.
How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation
C# D1 CSC 298 Elements of C# code (part 2). C# D2 Writing a class (or a struct)  Similarly to Java or C++  Fields: to hold the class data  Methods:
Introduction to Building Windows 8.1 & Windows Phone Applications.
CET203 SOFTWARE DEVELOPMENT Session 1A Revision of Classes.
Best Practices. Contents Bad Practices Good Practices.
1 Abstract Classes “I prefer Agassiz in the abstract, rather than in the concrete.” CS Computer Science II.
Defining Classes Classes, Fields, Constructors, Methods, Properties SoftUni Team Technical Trainers Software University
Information and Computer Sciences University of Hawaii, Manoa
Introduction to C#. Why C#? Develop on the Following Platforms ASP.NET Native Windows Windows 8 / 8.1 Windows Phone WPF Android (Xamarin) iOS (Xamarin)
Lecture 101 CS110 Lecture 10 Thursday, February Announcements –hw4 due tonight –Exam next Tuesday (sample posted) Agenda –questions –what’s on.
CS0007: Introduction to Computer Programming Classes: Documentation, Method Overloading, Scope, Packages, and “Finding the Classes”
Advanced C# Types Tom Roeder CS fa. From last time out parameters difference is that the callee is required to assign it before returning not the.
Bill Campbell, UMB Microsoft's.NET C# and The Common Language Runtime.
1 9/6/05CS360 Windows Programming CS360 Windows Programming.
Lab 4 - Variables. Information Hiding General Principle: – Restrict the access to variables and methods as much as possible Can label instance variables.
CLASSES AND OBJECTS Object-Oriented Basics. Vocabulary Review – C++ Class Object Instance this new Constructor Default constructor Access (private/public/protected)
Chain of Responsibility A graphical user interface and a user that needs help; a security system with multiple sensors; a banking automated coin storage.
CS305j Introduction to Computing Classes II 1 Topic 24 Classes Part II "Object-oriented programming as it emerged in Simula 67 allows software structure.
Bank Account Example public class BankAccount { private double balance; public static int totalAccounts = 0; public BankAccount() { balance = 0; totalAccounts++;
Principles of Object Oriented Design
PRINCIPLES OF OBJECT ORIENTED DESIGN S.O.L.I.D. S.O.L.I.D Principles What is SOLID?  Acrostic of 5 Principles:  The Single Responsibility Principle.
Introduction to Collections. Collections Collections provide a way of organizing related data in a model Different types of collections have different.
Generics & Collection Classes Version 1.0. Topics Generic Methods and Classes Generic Collection Classes List Enumerators Queue Stack LinkedList.
Topics Instance variables, set and get methods Encapsulation
©2000, John Wiley & Sons, Inc. Horstmann/Java Essentials, 2/e Chapter 3: An Introduction to Classes 1 Chapter 3 An Introduction to Classes.
CS180 Recitation Chapter 7: Defining Your Own Classes II.
Aplicativos para Internet Prof.ª Erika Miranda Prof. Wolley W. Silva.
© 2011 Pearson Education, publishing as Addison-Wesley Chapter 1: Computer Systems Presentation slides for Java Software Solutions for AP* Computer Science.
Basic Class Structure. Class vs. Object class - a template for building an object –defines the instance data that the object will hold –defines instance.
Classes CS 162 (Summer 2009). Parts of a Class Instance Fields Methods.
Java Best Practices Java Fundamentals & Object-Oriented Programming MELJUN CORTES, MBA,MPA,BSCS.
Sistemas Operativos Introdução. Sistema Operativo - definição De maneira menos informal podemos definir Sistema Operativo, como sendo o Software fundamental.
Arduino CHIP. Pins analógicos – (1 de 2) Recordar: Analog In - pin 0 ao 5 – analog to digital Recebe sinais analógicos e transforma-os em sinais digitais.
C# for C++ Programmers 1.
Data Structures and Algorithms revision
A Review or Brief Introduction
Code Review and Walkthroughs
Module 5: Common Type System
Methods Attributes Method Modifiers ‘static’
Lecture 7 Designing Classes
CS230 Tutorial Week 3.
Implementing Classes Yonglei Tao.
Chapter 11 – Interfaces and Polymorphism
Yung-Hsiang Lu Purdue University
How to Write a Testable Question
CLASS DEFINITION (> 1 CONSTRUCTOR)
בניית מחלקות.
null, true, and false are also reserved.
Writing Methods AP Computer Science A.
Interfaces in Java.
More on Thread Safety CSE451 Andrew Whitaker.
Inner Classes.
Recap Week 2 and 3.
JAVA CLASSES.
Visual Programming COMP-315
Chap 2. Identifiers, Keywords, and Types
OOP Aga private institute for computer science 5th grade
Presentation transcript:

Object Calisthenics Gabriel Heming

Gabriel Heming E-mail: gabriel.heming@hotmail.com

ORIGEM Cal • is • then • ics - /ˌkaləsˈTHeniks/ Origem grega; Exercícios no contexto de ginástica.

ORIGEM The ThoughtWorks Anthology - Jeff Bay; Conjunto de exercícios; Nove regras (não universais);

MOTIVAÇÃO Manutenibilidade; Legibilidade; Testabilidade; Compreensão.

RESUMINDO

Only one level of indentation per method; RULE #1: Only one level of indentation per method;

1 2 3 public String Board() { StringBuilder buf = new StringBuilder(); if (this.Data.Length >= 3) for (int i = 0; i < this.Data.Length; i++) for (int j = 0; j < this.Data[i].Length; j++) buf.Append(this.Data[i][j]); } buf.Append("\n"); return buf.ToString(); Validação 1 2 3 8

StringBuilder buf = new StringBuilder(); if (this.Data.Length < 3) public String Board() { StringBuilder buf = new StringBuilder(); if (this.Data.Length < 3) return buf.ToString(); } for (int i = 0; i < this.Data.Length; i++) for (int j = 0; j < this.Data[i].Length; j++) buf.Append(this.Data[i][j]); buf.Append("\n"); Early return 9

EXTRACT METHOD Martin Fowler

StringBuilder buf = new StringBuilder(); if (this.Data.Length < 3) public String Board() { StringBuilder buf = new StringBuilder(); if (this.Data.Length < 3) return buf.ToString(); } for (int i = 0; i < this.Data.Length; i++) buf.Append(this.CollectColumns(this.Data[i])); buf.Append("\n"); public String CollectColumns(string[] data) foreach (string row in data) buf.Append(row); 11

if (this.Data.Length < 3) return buf.ToString(); public String Board() { if (this.Data.Length < 3) return buf.ToString(); return this.CollectRows(this.Data); } public String CollectRows(string[][] data) StringBuilder buf = new StringBuilder(); foreach (string[] row in data) buf.Append(this.CollectColumns(row)); buf.Append("\n"); return buf.ToString(); public String CollectColumns(string[] data) foreach (string row in data) buf.Append(row); 12

Muito simples?

public static void SitefPaymentsAbort(Sales sales) { foreach (Payment payment in sales.Payments) if (payment.objSitefProvider != null && !string.IsNullOrEmpty(payment.objSitefProvider.receiptNumber)) payment.objSitefProvider.Abort(payment.objSitefProvider.receiptNumber, payment.objSitefProvider.DateTime); } foreach (TenderLineItem tenderlineitem in ((RetailTransaction)sales.transaction).TenderLines) if (tenderlineitem.LineId == payment.tenderLineItem.LineId) if (tenderlineitem is GiftCertificateTenderLineItem) if (sales.application.TransactionServices.CheckConnection()) bool released = true; string comment = ""; sales.application.TransactionServices.GiftCardRelease(ref released, ref comment, ((GiftCertificateTenderLineItem)tenderlineitem).SerialNumber); 14

public static void SitefPaymentsAbort(Sales sales) { foreach (Payment payment in sales.Payments) SalesOrder.SitefPaymentAbort(sales , payment); } private static void SitefPaymentAbort(Sales sales, Payment payment) if (payment.objSitefProvider != null && !string.IsNullOrEmpty(payment.objSitefProvider.receiptNumber)) payment.objSitefProvider.Abort(payment.objSitefProvider.receiptNumber, payment.objSitefProvider.DateTime); foreach (TenderLineItem tenderlineitem in ((RetailTransaction)sales.transaction).TenderLines) if (tenderlineitem.LineId == payment.tenderLineItem.LineId) if (tenderlineitem is GiftCertificateTenderLineItem) if (sales.application.TransactionServices.CheckConnection()) bool released = true; string comment = ""; sales.application.TransactionServices.GiftCardRelease(ref released, ref comment, ((GiftCertificateTenderLineItem)tenderlineitem).SerialNumber); 15

private static void SitefPaymentAbort(Sales sales, Payment payment) { /** código omitido **/ foreach (TenderLineItem tenderlineitem in ((RetailTransaction)sales.transaction).TenderLines) if (tenderlineitem.LineId == payment.tenderLineItem.LineId) if (tenderlineitem is GiftCertificateTenderLineItem) if (sales.application.TransactionServices.CheckConnection()) bool released = true; string comment = ""; sales.application.TransactionServices.GiftCardRelease(ref released, ref comment, ((GiftCertificateTenderLineItem)tenderlineitem).SerialNumber); } Validações 16

private static void SitefPaymentAbort(Sales sales, Payment payment) { /** código omitido **/ IEnumerable<TenderLineItem> tenderLineItemList = ((RetailTransaction)sales.transaction).TenderLines.Where( tenderLineItem => tenderLineItem.LineId == payment.tenderLineItem.LineId && tenderLineItem is GiftCertificateTenderLineItem ); foreach (TenderLineItem tenderlineitem in tenderLineItemList) if (sales.application.TransactionServices.CheckConnection()) bool released = true; string comment = ""; sales.application.TransactionServices.GiftCardRelease(ref released, ref comment, ((GiftCertificateTenderLineItem)tenderlineitem).SerialNumber); } 17

private static void SitefPaymentAbort(Sales sales, Payment payment) { /** código omitido **/ IEnumerable<TenderLineItem> tenderLineItemList = ((RetailTransaction)sales.transaction).TenderLines.Where( tenderLineItem => tenderLineItem.LineId == payment.tenderLineItem.LineId && tenderLineItem is GiftCertificateTenderLineItem ); foreach (TenderLineItem tenderlineitem in tenderLineItemList) SalesOrder.GiftCardRelease(sales, tenderLineItem); } private static void GiftCardRelease(SalesOrder sales, TenderLineItem tenderlineitem) if (sales.application.TransactionServices.CheckConnection()) bool released = true; string comment = ""; sales.application.TransactionServices.GiftCardRelease(ref released, ref comment, ((GiftCertificateTenderLineItem)tenderlineitem).SerialNumber); 18

public static void SitefPaymentsAbort(Sales sales) { foreach (Payment payment in sales.Payments) SalesOrder.SitefPaymentAbort(sales , payment); } private static void SitefPaymentAbort(Sales sales, Payment payment) if (payment.objSitefProvider != null && !string.IsNullOrEmpty(payment.objSitefProvider.receiptNumber)) payment.objSitefProvider.Abort(payment.objSitefProvider.receiptNumber, payment.objSitefProvider.DataHoraTransacao); IEnumerable<TenderLineItem> tenderLineItemList = ((RetailTransaction)sales.transaction).TenderLines.Where( tenderLineItem => tenderLineItem.LineId == payment.tenderLineItem.LineId && tenderLineItem is GiftCertificateTenderLineItem ); foreach (TenderLineItem tenderlineitem in tenderLineItemList) SalesOrder.GiftCardRelease(sales, tenderLineItem); private static void GiftCardRelease(SalesOrder sales, TenderLineItem tenderlineitem) if (sales.application.TransactionServices.CheckConnection()) bool released = true; string comment = ""; sales.application.TransactionServices.GiftCardRelease(ref released, ref comment, ((GiftCertificateTenderLineItem)tenderlineitem).SerialNumber); 19

BENEFÍCIOS S.R.P. (Single Responsibility Principle); Redução lógica por métodos; Legibilidade; Reusabilidade.

RULE #2: Don’t use the else keyword

Por que?

COMPLEXIDADE CICLOMÁTICA

Defensive Programming

public Entity Create(Entity entity) { if (entity.IsValid()) Repository repository = this.GetRepository(entity); if (!repository.Exists(entity)) return repository.Save(entity); } else throw new ArgumentException("The entity already exists"); throw new ArgumentException("Invalid entity"); 25

public Entity Create(Entity entity) { if (!entity.IsValid()) throw new ArgumentException("Invalid entity"); } Repository repository = this.GetRepository(entity); if (!repository.Exists(entity)) return repository.Save(entity); else throw new ArgumentException("The entity already exists"); 26

public Entity Create(Entity entity) { if (!entity.IsValid()) throw new ArgumentException("Invalid entity"); } Repository repository = this.GetRepository(entity); if (repository.Exists(entity)) throw new ArgumentException("The entity already exists"); return repository.Save(entity); 27

OUTRAS ABORDAGENS Chain of Responsibility Pattern; State Pattern.

BENEFÍCIOS Evita duplicidade; Aumenta a legibilidade; Reduz a complexidade ciclomática.

RULE #3: Wrap all primitives  and STRINGS

 Primitive Obsession  anti-pattern

SOMENTE TIPOS COM COMPORTAMENTO

87,43 Sub 0?? 77,43 ????????? Add -10?? class BankAccount { private double amount; public void Add(double money) this.amount += money; } public void Sub(double money) this.amount -= money; public double Total() return this.amount; BankAccount account = new BankAccount(); account->Add(10); account->Add(12.25); account->Add(27.50); account->Add(55); account->Sub(17.32); account->Total(); 87,43 account->Add(-10); account->Sub(0); account->Total(); Sub 0?? 77,43 ????????? Add -10?? 33

Lógica duplicada class BankAccount { private double amount; public void Add(double money) if (money <= 0) throw new ArgumentException("money não pode ser igual ou menor que zero"); } this.amount += money; public void Sub(double money) this.amount -= money; public double Total() return this.amount; Lógica duplicada 34

private double amount; public Money(double amount) if (money <= 0) class Money { private double amount; public Money(double amount) if (money <= 0) throw new ArgumentException("money não pode ser igual ou menor que zero"); } this.amount = amount; public double GetAmount() return this.amount; class BankAccount { private double amount; public void Add(Money money) this.amount += money->GetAmount(); } public void Sub(Money money) this.amount -= money->GetAmount(); public double Total() return this.amount; BankAccount account = new BanckAccount(); account->Add(new Money(10));  account->Add(new Money(-10)); // throw ArgumentException 35

BENEFÍCIOS Evita duplicidade; Encapsulamento; Domain Driven Design.

First class collections RULE #4: First class collections

public List<Address> AddressList { get; internal set; } } public class Person { public List<Address> AddressList { get; internal set; } } public class Address public Type Type { get ; set; } public enum Type Residential, Commercial List<Address> residentialAddressList = person.AddressList.Where( address => address.Type == Type.Residential ).ToList() List<Address> residentialAddressList = person.AddressList.Where( address => address.Type == Type.Commercial ).ToList() 38

E SE PRECISAR FILTRAR EM DIFERENTES LUGARES?

Responsabilidades demais class Person { public List<Address> AddressList { get; internal set; } public List<Address> GetResidentialAddressList() return this.AddressList.Where( address => address.Type == Type.Residential).ToList(); } public List<Address> GetCommercialAddressList() address => address.Type == Type.Commercial).ToList(); Responsabilidades demais List<Address> residentialAddressList = person.GetResidentialAddressList(); List<Address> commercialAddressList = person.GetCommercialAddressList(); 40

CADA UM COM SUA RESPONSABILIDADE

public class AddressCollection { public List<Address> GetResidentialAddressList() return this.AddressList.Where( address => address.Type == Type.Residential).ToList(); } public List<Address> GetCommercialAddressList() address => address.Type == Type.Commercial).ToList(); public class Person public AddressCollection AddressCollection { get; internal set; } List<Address> residentialAddressList = person.AddressCollection.GetResidentialAddressList(); List<Address> commercialAddressList = person.AddressCollection.GetCommercialAddressList(); 42

BENEFÍCIOS S.R.P. (Single Responsibility Principle); Evita duplicação; Manutenibilidade.

RULE #5: One dot per line

TRAIN WRECKS Robert UncleBob Martin

this.Repository.Database.Config.SetAttribute("attribute" , "value"); E se houver um null? 46

Null object?

POR QUE NÃO? Esconde um problema de encapsulamento; Difícil de debugar e tratar exceções; O código deve ser reestruturado e tomar consciência da existência dele; Prejudica a leitura e o entendimento.

LAW OF DEMETER

this.Repository.SetDatabaseConfig("attribute", "value"); Nem sempre é aplicável 50

EXCEÇÕES Fluent Interface; Builders (ex.: Query Builder, Link Builder, etc...);

BENEFÍCIOS Lei de Demeter; O.C.P (Open/Closed Principle); Legibilidade; Testabilidade; Debug.

RULE #6: Don’t abbreviate

POR QUE ABREVIAR? Escrita repetitiva? Nomes muito longos? “There are 2 hard problems in computer science: cache invalidation, naming things, and off-by-1 errors.”

BENEFÍCIOS S.R.P. (Single Responsibility Principle); Comunicação; Legibilidade; Manutenibilidade.

Keep all entities small RULE #7: Keep all entities small

DIRETRIZES Classes com 50 linhas; Leitura com pouco uso de scroll; Apenas desenvolva o que for utilizar.

BENEFÍCIOS S.R.P. (Single Responsibility Principle); Legibilidade; Encapsulamento; Segregação; Coesão e Coerência.

No classes with more than two instance variables RULE #8: No classes with more than two instance variables

ESSA É DIFÍCIL

List<String> names; class Name { String first; String middle; String last; } class Name { Surname family; GivenNames given; } class Surname String family; class GivenNames List<String> names; 61

Por que somente duas?

COMPLEMENTAR A REGRA #2

BENEFÍCIOS S.R.P. (Single Responsability Principle); Baixo acoplamento; Encapsulamento; Coesão e Coerência; Testabilidade.

No getters / setters / properties RULE #9: No getters / setters / properties

POR QUE? Simplesmente uma questão comportamental.

public int X { get; set; } public int Y { get; set; } } class Rectangle { public int X { get; set; } public int Y { get; set; } } Rectangle rectangle = new Rectangle() { X = 10, Y = 5 }; int area = rectangle.X * rectangle.Y; 67

TELL, DON’T ASK!

public Rectangle(int x , int y) this.X = x; this.Y = y; } class Rectangle { private int X; private int Y; public Rectangle(int x , int y) this.X = x; this.Y = y; } public int TotalArea() return this.X * this.Y; Rectangle rectangle = new Rectangle(10, 5); int area = rectangle.TotalArea(); 69

BENEFÍCIOS O.C.P (Open/Closed Principle); Encapsulamento.

CONSIDERAÇÕES

QUESTIONS? Thanks!