SlideShare una empresa de Scribd logo
1 de 69
Fernando Escolar
@fernandoescolar
fernando.escolar@tokiota.com
Code Smells
Y
A
X B
public void CalculateTotalPrice()
{
//calculates taxes
var taxes = 0.0m;
foreach (var product in this.productLines)
{
// ...
taxes += product.Price / product.TaxesPercent * 100;
}
//calculates price
var price = 0.0m;
foreach (var product in this.productLines)
{
// ...
price += product.Price * product.Unit;
}
this.TotalPrice = price + taxes;
}
public void CalculateTotalPrice()
{
var taxes = this.CalculateTaxes();
var price = this.CalculatePrice();
this.TotalPrice = price + taxes;
}
public decimal CalculateTaxes()
{
// ...
return taxes;
}
public decimal CalculatePrice()
{
// ...
return price;
}
public class User
{
// ...
}
public class Product
{
// ...
}
public class ProductLine
{
// ...
}
public class Order
{
// ...
}
public class Customer
{
private string name;
private string lastName;
private string streetType;
private string streetName;
private string streetNumber;
private string floorNumber;
private string doorNumber;
private string postalCode;
private string city;
private string state;
private string country;
private string phone;
private string email;
}
public class Customer {
private string name;
private string lastname;
private string phone;
private string email;
private Address address;
}
public class Address {
private string streetType;
private string streetName;
private string streetNumber;
private string floorNumber;
private string doorNumber;
private string postalCode;
private string city;
private string state;
private string country;
}
public void Draw(int x, int y, int width, int heigth,
int borderSize,
Color borderColor, Color backgroundColor)
{
// ...
}
public void Draw(BorderedRectangle rectangle)
{
// ...
}
public class Rectangle
{
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public Color Color { get; set; }
}
public class BorderedRectangle : Rectangle
{
public int BorderSize { get; set; }
public Color BorderColor { get; set; }
}
class Rectangle
{
public void Draw(int x, int y, int width, int height,
int borderSize, Color borderColor, Color backgroundColor)
{
this.DrawRectable(x, y, width, height, backgroundColor);
this.DrawRectangleBorder(x, y, width, height, borderSize,
borderColor);
}
private void DrawRectable(int x, int y, int width, int height,
Color color)
{
// ...
}
private void DrawRectangleBorder(int x, int y, int width,
int height, int borderSize, Color color)
{
// ...
}
public class Rectangle
{
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public Color Color { get; set; }
public void Draw() { /* ... */ }
}
public class BorderedRectangle : Rectangle
{
public int BorderSize { get; set; }
public Color BorderColor { get; set; }
public void Draw() { base.Draw(); /* ... */ }
}
namespace MyTech
{
class MyTechConnection { }
class MyTechConnectionHndl { }
class Order {
public bool Order(OrderRequest request) { /* ... */ }
}
class Inv
{
int Do(int a, string s, double d) { /* ... */ }
}
}
namespace MyTechnology
{
class Connection { }
class ConnectionHandler { }
class OrderManager {
public bool Request(Order order) { /* ... */ }
}
class Invoice
{
bool Pay(int userId, string account, double price) {
/* ... */
}
}
}
private const decimal USDolarChange = 1.13845m;
private const decimal BritishPoundsChange = 0.739373275m;
public enum MoneyTypes { Euro, USDolar, BritishPounds };
public decimal ConvertValue(decimal money, MoneyTypes type)
{
switch (type)
{
case MoneyTypes.Euro:
return money;
case MoneyTypes.USDolar:
return money * USDolarChange;
case MoneyTypes.BritishPounds:
return money * BritishPoundsChange;
default:
return money;
}
}
public class Euro {
public decimal Value { get; set; }
public virtual decimal GetConvertedValue()
{
return this.Value;
}
}
public class USDolar : Euro {
public override decimal GetConvertedValue()
{
return this.Value * USDolarChange;
}
}
public class BritishPounds : Euro {
public override decimal GetConvertedValue()
{
return this.Value * BritishPoundsChange;
}
}
public decimal GetDiscount()
{
var basePrice = quantity * itemPrice;
if (quantity > 1000)
return basePrice * 0.95;
else if (quantity > 500)
return 20.0d;
}
public decimal GetDiscount()
{
if (quantity > 1000)
return CalculateBasePrice() * 0.95;
else if (quantity > 500)
return 20.0d;
}
private decimal CalculateBasePrice()
{
return quantity * itemPrice;
}
abstract class Membership
{
public abstract IEnumerable<User> GetUsers();
public abstract IEnumerable<Profile> GetProfiles();
public abstract User Auth(string user, string password);
public abstract IEnumerable<Profile> GetUserProfile(User user);
}
class MyMembership : Membership
{
public override IEnumerable<User> GetUsers() {
throw new NotImplementedException(); }
public override IEnumerable<Profile> GetProfiles() {
throw new NotImplementedException(); }
public override User Auth(string user, string password) {
// ...
}
public override IEnumerable<Profile> GetUserProfile(User user) {
// ...
}
}
¿Liskov?
abstract class Membership
{
public abstract User Auth(string user, string password);
public abstract IEnumerable<Profile> GetUserProfile(User user);
}
class MyMembership : Membership
{
public override User Auth(string user, string password)
{
// ...
}
public override IEnumerable<Profile> GetUserProfile(User user)
{
// ...
}
}
class TokiotaService
{
// ...
}
class MicrosoftService
{
// ...
}
public IEnumerable<TokiotaItem> GetTokiotaItems()
{
return this.tokiotaService.GetProyects();
}
public IEnumerable<MicrosoftItem> GetMicrosoftItems()
{
return this.microsoftService.GetPartnerCollaborations();
}
class Item { /* ... */ }
class IAdapter
{
IEnumerable<Item> GetItems();
}
class MicrosoftAdapter : IAdapter { /* ... */ }
class TokiotaAdapter : IAdapter { /* ... */ }
public IEnumerable<Item> GetItems(IAdapter adapter)
{
return adapter.GetItems();
}
public decimal CalculateTotalPrice() {
if (this.isChristmas) {
return this.CalculateChristmas();
}
else {
if (this.HasDiscount()) {
return this.CalculateDiscounted(this.GetDiscount());
}
else {
if (this.isTimeOfSale) {
return this.CalculateDiscounted(this.GetSalesDiscount());
}
else
{
return this.CalculateStandard();
}
}
}
}
public decimal CalculateTotalPrice()
{
if (this.isChristmas)
return this.CalculateChristmas();
if (this.HasDiscount())
return this.CalculateDiscounted(this.GetDiscount());
if (this.isTimeOfSale)
return this.CalculateDiscounted(this.GetSalesDiscount());
return this.CalculateStandard();
}
class Customer
{
public string Name { get; set; }
public string LastName { get; set; }
public string toXML()
{
return @"<Customer>" +
"<Name>" +
this.Name +
"</Name>" +
"<LastName>" +
this.LastName +
"</LastName>" +
"</Customer>";
}
}
Open-Close?
class Customer
{
private readonly CustomerXmlSerializer serializer = ...;
public string Name { get; set; }
public string LastName { get; set; }
public string toXML()
{
return this.serializer.Serialize(this);
}
}
class CustomerXmlSerializer : XmlSerializer
{
public string Serialize(Customer c)
{
var sb = new StringBuilder();
sb.Append(this.StartTag("Customer"));
sb.Append(this.WriteTag("Name", c.Name));
sb.Append(this.WriteTag("LastName", c.LastName));
sb.Append(this.EndTag("Customer"));
}
class OrderManager
{
decimal CalculateOrderPrice(Product[] products, int[] units) {
/* ... */
}
}
class OrderViewModel
{
public Product[] Products { get; set; }
public int[] Units { get; set; }
}
class OrderService
{
void SendOrder(Product[] products, int[] units) { /* ... */ }
}
¿Y si queremos
añadir IVA?
class Order
{
public Product[] Products { get; set; }
public int[] Units { get; set; }
public decimal GetPrice() { /* ... */ }
}
class OrderManager
{
decimal CalculateOrderPrice(Order order) {
return order.GetPrice();
}
}
class OrderViewModel
{
public Order Order { get; set; }
}
class OrderService
{
void SendOrder(Order order) { /* ... */ }
}
class Vehicle { }
class Car : Vehicle { }
class Truck : Vehicle { }
class Motorbike : Vehicle { }
class VehicleXmlSerializer { }
class CarXmlSerializer : VehicleXmlSerializer { }
class TruckXmlSerializer : VehicleXmlSerializer { }
class MotorbikeXmlSerializer : VehicleXmlSerializer { }
Vehicle
Class
Car
Truck
Motorbike
Xml
Car
Truck
MotorBike
class VehicleXmlSerializer
{
public VehicleXmlSerializer(IToXmlStrategy[] strategies) { }
}
interface IToXmlStrategy { }
interface IToXmlStrategy<T> where T : Vehicle { }
class CarToXmlStrategy : IToXmlStrategy<Car> { }
class TruckTOXmlStrategy : IToXmlStrategy<Truck> { }
class MotorbikeToXmlStrategy : IToXmlStrategy<Motorbike> { }
class OrderViewModel
{
decimal CalculateTax() { return totalPrice * 0.21; }
}
class Invoice
{
decimal ShowTax() { return order.TotalPrice * 0.21; }
}
class ViewModel
{
public decimal Tax { get { return 21.0; } }
}
static class Globals
{
public const decimal TaxPercent = 21.0m;
public const decimal TaxDelta = TaxPercent / 100;
}
class OrderViewModel
{
decimal CalculateTax() { return totalPrice * Globals.TaxDelta; }
}
class Invoice
{
decimal ShowTax() { return order.TotalPrice * Globals.TaxDelta; }
}
class ViewModel
{
public decimal Tax { get { return Globals.TaxPercent; } }
}
class LazyClass
{
public static string FormatName(string name,
string lastname, string surname)
{
return string.Format("{1}, {0} ({2})",
name, lastname, surname);
}
}
Solo un método
llamada desde
solo un lugar
class CustomerInfo
{
public string Name { get; set; }
public string LastName { get; set; }
public string Surname { get; set; }
public override string ToString()
{
return string.Format("{1}, {0} ({2})",
this.Name,
this.LastName, this.Surname);
}
}
class Settings
{
public string Name { get; set; }
public string Host { get; set; }
public bool UseSsl { get; set; }
public int NumerOfConnections { get; set; }
}
class SettingsManager
{
public void Save(Settings settings) { /* ... */ }
public Settings Load() { /* ... */ }
}
Una clase con las propiedades y
otra con los métodos
class Settings
{
public string Name { get; set; }
public string Host { get; set; }
public bool UseSsl { get; set; }
public int NumerOfConnections { get; set; }
public void Save() { /* ... */ }
public void Load() { /* ... */ }
}
class MyClass
{
public int MyProperty { get; set; }
public string Name { get; set; }
public void Process() { /* ... */ }
public void Send() { /* ... */ }
}
class MyClassOld
{
public string Name { get; set; }
public void Process() { /* ... */ }
}
class MyClass
{
public int MyProperty { get; set; }
public string Name { get; set; }
public void Process() { /* ... */ }
public void Send() { /* ... */ }
}
class CustomerController {
public ActionResult Edit(Customer customer) {
if (Model.IsValid) {
this.customerRepository.InsertOrUpdate(customer);
this.customerRepository.Save();
return RedirectToAction("Index");
}
return View();
}
}
class EmployeeController {
public ActionResult Edit(Employee employee) {
if (Model.IsValid) {
this.employeeRepository.InsertOrUpdate(employee);
this.employeeRepository.Save();
return RedirectToAction("Index");
}
return View();
}
}
class ControllerBase<TEntity> where TEntity : IEntity
{
IRepository<Employee> repository;
public ActionResult Edit(TEntity entity)
{
if (Model.IsValid)
{
this.repository.InsertOrUpdate(entity);
this.repository.Save();
return RedirectToAction("Index");
}
return View();
}
}
class CustomerController : ControllerBase<Customer> { }
class EmployeeController : ControllerBase<Employee> { }
public interface ITextFormatStrategy { string Format(string input); }
public class CommentTextFormatContext {
private ITextFormatStrategy strategy;
public CommentTextFormatContext(ITextFormatStrategy strategy) {
this.strategy = strategy;
}
public int ExecuteStrategy(string input) {
return strategy.Format(input);
}
}
public class RemoveHtmlTagsStrategy : ITextFormatStrategy {
public string Format(string input) {
return Regex.Replace(input, @"<[^>]*>", string.Empty);
}
}
¿Solo una estrategia? YAGNI
public class Comment
{
public void SetMessage(string message)
{
this.Text = Regex.Replace(message, @"<[^>]*>", string.Empty);
}
}
// calculates the total price of the order
public decimal Calculate()
{
// in christmas time
if (DateTime.Now >= new DateTime(DateTime.Now.Year, 12, 25)
&& DateTime.Now <= new DateTime(DateTime.Now.Year + 1, 1, 5))
{
// it has a discount of 10%
return this.TotalPrice * 0.9;
}
else
{
return thisw.TotalPrice;
}
}
public decimal CalculateOrderTotalPrice()
{
if (IsChirstmasTime()) {
return this.ApplyDiscountPercentage(10);
}
else {
return this.TotalPrice;
}
}
private decimal ApplyDiscountPercentage(int percentage)
{
return this.TotalPrice * (100 - percentage) / 100;
}
private static bool IsChirstmasTime()
{
return DateTime.Now >= new DateTime(DateTime.Now.Year, 12, 25)
&& DateTime.Now <= new DateTime(DateTime.Now.Year + 1, 1, 5);
}
public class Product
{
public bool HasBeenOrdered(Order order)
{
return order.Products.Contains(this);
}
}
public class Order
{
public List<Product> Products { get; set; }
}
public class Product { }
public class Order
{
public List<Product> Products { get; set; }
public bool HasBeenOrdered(Product product)
{
return this.Products.Contains(product);
}
}
public class Customer
{
public string Name { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string Address { get; set; }
}
public class Order
{
private Customer customer;
public string GetSummary()
{
var summary = string.Format("{0} {1}n{2}n{3}",
this.customer.Name,
this.customer.LastName,
this.customer.PhoneNumber,
this.customer.Address);
summary += "n" + this.TotalPrice + " €";
return summary;
}
}
public class Customer
{
public string Name { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string Address { get; set; }
public override string ToString() {
return string.Format("{0} {1}n{2}n{3}",
this.Name,
this.LastName,
this.PhoneNumber,
this.Address);
}
}
public class Order
{
private Customer customer;
public string GetSummary() {
return this.customer.ToString() + "n" + this.TotalPrice + " €";
}
}
public decimal CalculateTotalPrice()
{
/* ... */
if (this.Customer.Address.Country.IsEuropean)
{
/* ... */
}
/* ... */
}
public decimal CalculateTotalPrice()
{
/* ... */
if (this.Customer.IsEuropean)
{
/* ... */
}
/* ... */
}
public class Customer
{
public bool IsEuropean
{
get
{
return this.Address.IsEuropean;
}
}
}
class MyConnection
{
private SqlConnection connection = new SqlConnection();
public string ConnectionString
{
get { return this.connection.ConnectionString; }
}
public void Open()
{
this.connection.Open();
}
public MyCommand CreateCommand()
{
return new MyCommand(this.connection.CreateCommand());
}
}
SqlConnection connection = new SqlConnection();
class XmlSerializer
{
public string StartTagString { get; set; }
public string EndTagString { get; set; }
public XmlSerializer()
{
StartTagString = "<{0}>";
EndTagString = "</{0}>";
}
protected string WriteTag(string name, string value) {
return StartTag(name) + value + EndTag(name);
}
protected string StartTag(string name) {
return string.Format(StartTagString, name);
}
protected string EndTag(string name) {
return string.Format(EndTagString, name);
}
}
class XmlSerializer
{
private const string StartTagString = "<{0}>";
private const string EndTagString = "</{0}>";
protected string WriteTag(string name, string value)
{
return StartTag(name) + value + EndTag(name);
}
protected string StartTag(string name)
{
return string.Format(StartTagString, name);
}
protected string EndTag(string name)
{
return string.Format(EndTagString, name);
}
}
Fernando Escolar
@fernandoescolar
fernando.escolar@tokiota.com
¡¡¡Si te ha gustado no olvides
rellenar la encuesta!!!
Thanks
Y
A
X B

Más contenido relacionado

Destacado

Social networking as an esol strategy
Social networking as an esol strategySocial networking as an esol strategy
Social networking as an esol strategyRhonda101
 
Express business health check
Express business health checkExpress business health check
Express business health checkQuek Joo Chay
 
ульяновск саммит
ульяновск саммитульяновск саммит
ульяновск саммитfpolicy_ru
 
Project proposal
Project proposalProject proposal
Project proposalMoeed Awais
 
Деинституционализацията в България!
Деинституционализацията в България!Деинституционализацията в България!
Деинституционализацията в България!CIL - Sofia
 
Presentation1
Presentation1Presentation1
Presentation1kk11711
 
Hjc bb seminar - blackbaud presentation vancouver draft one sept 6 2012
Hjc bb seminar - blackbaud presentation vancouver draft one sept 6 2012Hjc bb seminar - blackbaud presentation vancouver draft one sept 6 2012
Hjc bb seminar - blackbaud presentation vancouver draft one sept 6 2012Ashley Donald
 
Mi carro nuevo - Survey 2012
Mi carro nuevo - Survey 2012Mi carro nuevo - Survey 2012
Mi carro nuevo - Survey 2012RedMasAdv
 
Report of linuxcon japan 2013
Report of linuxcon japan 2013Report of linuxcon japan 2013
Report of linuxcon japan 2013Naruto TAKAHASHI
 
freeCodeCamp Tokyo Meetup #18
freeCodeCamp Tokyo Meetup #18freeCodeCamp Tokyo Meetup #18
freeCodeCamp Tokyo Meetup #18健太 田上
 
Interest only pilot v3 14.12.12
Interest only pilot v3 14.12.12Interest only pilot v3 14.12.12
Interest only pilot v3 14.12.12HML Ltd
 
The "Social" Relationship between Marketing & Recruiting for TMA _ Celinda Ap...
The "Social" Relationship between Marketing & Recruiting for TMA _ Celinda Ap...The "Social" Relationship between Marketing & Recruiting for TMA _ Celinda Ap...
The "Social" Relationship between Marketing & Recruiting for TMA _ Celinda Ap...Celinda Appleby
 
Body paragraph and midtest
Body paragraph and midtestBody paragraph and midtest
Body paragraph and midtestPenyelamatJanda
 
Spring gourmet-dinner
Spring gourmet-dinnerSpring gourmet-dinner
Spring gourmet-dinnerBigAl72
 

Destacado (20)

Social networking as an esol strategy
Social networking as an esol strategySocial networking as an esol strategy
Social networking as an esol strategy
 
Express business health check
Express business health checkExpress business health check
Express business health check
 
ульяновск саммит
ульяновск саммитульяновск саммит
ульяновск саммит
 
Project proposal
Project proposalProject proposal
Project proposal
 
Деинституционализацията в България!
Деинституционализацията в България!Деинституционализацията в България!
Деинституционализацията в България!
 
Presentation1
Presentation1Presentation1
Presentation1
 
Hjc bb seminar - blackbaud presentation vancouver draft one sept 6 2012
Hjc bb seminar - blackbaud presentation vancouver draft one sept 6 2012Hjc bb seminar - blackbaud presentation vancouver draft one sept 6 2012
Hjc bb seminar - blackbaud presentation vancouver draft one sept 6 2012
 
Mi carro nuevo - Survey 2012
Mi carro nuevo - Survey 2012Mi carro nuevo - Survey 2012
Mi carro nuevo - Survey 2012
 
Report of linuxcon japan 2013
Report of linuxcon japan 2013Report of linuxcon japan 2013
Report of linuxcon japan 2013
 
freeCodeCamp Tokyo Meetup #18
freeCodeCamp Tokyo Meetup #18freeCodeCamp Tokyo Meetup #18
freeCodeCamp Tokyo Meetup #18
 
Interest only pilot v3 14.12.12
Interest only pilot v3 14.12.12Interest only pilot v3 14.12.12
Interest only pilot v3 14.12.12
 
The "Social" Relationship between Marketing & Recruiting for TMA _ Celinda Ap...
The "Social" Relationship between Marketing & Recruiting for TMA _ Celinda Ap...The "Social" Relationship between Marketing & Recruiting for TMA _ Celinda Ap...
The "Social" Relationship between Marketing & Recruiting for TMA _ Celinda Ap...
 
Freshwater matters Nov 2015
Freshwater matters Nov 2015 Freshwater matters Nov 2015
Freshwater matters Nov 2015
 
Body paragraph and midtest
Body paragraph and midtestBody paragraph and midtest
Body paragraph and midtest
 
Klíma 7 előnye
Klíma  7 előnyeKlíma  7 előnye
Klíma 7 előnye
 
Public Speaking For Scientists
Public Speaking For ScientistsPublic Speaking For Scientists
Public Speaking For Scientists
 
Spring gourmet-dinner
Spring gourmet-dinnerSpring gourmet-dinner
Spring gourmet-dinner
 
Thackeray ehfi sefs8
Thackeray ehfi sefs8Thackeray ehfi sefs8
Thackeray ehfi sefs8
 
Guns_in_the_Workplace
Guns_in_the_WorkplaceGuns_in_the_Workplace
Guns_in_the_Workplace
 
Examen
ExamenExamen
Examen
 

Similar a DotNet Conference: code smells

Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo....NET Conf UY
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languagesRafael Winterhalter
 
Combatendo code smells em Java
Combatendo code smells em Java Combatendo code smells em Java
Combatendo code smells em Java Emmanuel Neri
 
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBTDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBtdc-globalcode
 
How to Start Test-Driven Development in Legacy Code
How to Start Test-Driven Development in Legacy CodeHow to Start Test-Driven Development in Legacy Code
How to Start Test-Driven Development in Legacy CodeDaniel Wellman
 
Refactoring - Mejorando el diseño del código existente
Refactoring - Mejorando el diseño del código existenteRefactoring - Mejorando el diseño del código existente
Refactoring - Mejorando el diseño del código existenteMariano Sánchez
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETtdc-globalcode
 
assignmentTwoCar.javaassignmentTwoCar.javapackage assignmentTw.docx
assignmentTwoCar.javaassignmentTwoCar.javapackage assignmentTw.docxassignmentTwoCar.javaassignmentTwoCar.javapackage assignmentTw.docx
assignmentTwoCar.javaassignmentTwoCar.javapackage assignmentTw.docxssuser562afc1
 
Csharp4 inheritance
Csharp4 inheritanceCsharp4 inheritance
Csharp4 inheritanceAbed Bukhari
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy codeShriKant Vashishtha
 
Dependency Injection and Aspect Oriented Programming presentation
Dependency Injection and Aspect Oriented Programming presentationDependency Injection and Aspect Oriented Programming presentation
Dependency Injection and Aspect Oriented Programming presentationStephen Erdman
 
Java Generics
Java GenericsJava Generics
Java Genericsjeslie
 

Similar a DotNet Conference: code smells (20)

Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
Code Smells y Refactoring o haciendo que nuestro codigo huela (y se vea) mejo...
 
Solid principles
Solid principlesSolid principles
Solid principles
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languages
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
Combatendo code smells em Java
Combatendo code smells em Java Combatendo code smells em Java
Combatendo code smells em Java
 
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDBTDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
TDC2016POA | Trilha .NET - CQRS e ES na prática com RavenDB
 
How to Start Test-Driven Development in Legacy Code
How to Start Test-Driven Development in Legacy CodeHow to Start Test-Driven Development in Legacy Code
How to Start Test-Driven Development in Legacy Code
 
Functional Programming with C#
Functional Programming with C#Functional Programming with C#
Functional Programming with C#
 
Refactoring - Mejorando el diseño del código existente
Refactoring - Mejorando el diseño del código existenteRefactoring - Mejorando el diseño del código existente
Refactoring - Mejorando el diseño del código existente
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NET
 
Java doc Pr ITM2
Java doc Pr ITM2Java doc Pr ITM2
Java doc Pr ITM2
 
assignmentTwoCar.javaassignmentTwoCar.javapackage assignmentTw.docx
assignmentTwoCar.javaassignmentTwoCar.javapackage assignmentTw.docxassignmentTwoCar.javaassignmentTwoCar.javapackage assignmentTw.docx
assignmentTwoCar.javaassignmentTwoCar.javapackage assignmentTw.docx
 
Csharp4 inheritance
Csharp4 inheritanceCsharp4 inheritance
Csharp4 inheritance
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
 
Exam2prep
Exam2prepExam2prep
Exam2prep
 
Dependency Injection and Aspect Oriented Programming presentation
Dependency Injection and Aspect Oriented Programming presentationDependency Injection and Aspect Oriented Programming presentation
Dependency Injection and Aspect Oriented Programming presentation
 
OOP Lab Report.docx
OOP Lab Report.docxOOP Lab Report.docx
OOP Lab Report.docx
 
Java Generics
Java GenericsJava Generics
Java Generics
 
Csharp4 generics
Csharp4 genericsCsharp4 generics
Csharp4 generics
 
Joy of scala
Joy of scalaJoy of scala
Joy of scala
 

Más de Fernando Escolar Martínez-Berganza

Roslyn: Hello from the other compiler - dotNet Spain Conference 2016
Roslyn: Hello from the other compiler - dotNet Spain Conference 2016Roslyn: Hello from the other compiler - dotNet Spain Conference 2016
Roslyn: Hello from the other compiler - dotNet Spain Conference 2016Fernando Escolar Martínez-Berganza
 

Más de Fernando Escolar Martínez-Berganza (20)

Por qué todo lo que subo a azure esta mal
Por qué todo lo que subo a azure esta malPor qué todo lo que subo a azure esta mal
Por qué todo lo que subo a azure esta mal
 
Deconstrucción de SOLID
Deconstrucción de SOLIDDeconstrucción de SOLID
Deconstrucción de SOLID
 
Gapand - por qué odio git?
Gapand - por qué odio git?Gapand - por qué odio git?
Gapand - por qué odio git?
 
Betabeers - continuous deployment
Betabeers - continuous deploymentBetabeers - continuous deployment
Betabeers - continuous deployment
 
Devops RoadShow: load testing and autoscale
Devops RoadShow: load testing and autoscaleDevops RoadShow: load testing and autoscale
Devops RoadShow: load testing and autoscale
 
Roslyn: Hello from the other compiler - dotNet Spain Conference 2016
Roslyn: Hello from the other compiler - dotNet Spain Conference 2016Roslyn: Hello from the other compiler - dotNet Spain Conference 2016
Roslyn: Hello from the other compiler - dotNet Spain Conference 2016
 
Reconnect 2015 - ALM VSTS
Reconnect 2015 - ALM VSTSReconnect 2015 - ALM VSTS
Reconnect 2015 - ALM VSTS
 
Codemotion 2015 - Unit Testing
Codemotion 2015 - Unit TestingCodemotion 2015 - Unit Testing
Codemotion 2015 - Unit Testing
 
Unit testing en Windows 10
Unit testing en Windows 10Unit testing en Windows 10
Unit testing en Windows 10
 
Las cronicas de redis
Las cronicas de redisLas cronicas de redis
Las cronicas de redis
 
Redis: no solo una caché
Redis: no solo una cachéRedis: no solo una caché
Redis: no solo una caché
 
Foro de Arquitectos: caché en azure a fondo
Foro de Arquitectos: caché en azure a fondoForo de Arquitectos: caché en azure a fondo
Foro de Arquitectos: caché en azure a fondo
 
Codemotion: descubriendo las cachés
Codemotion: descubriendo las cachésCodemotion: descubriendo las cachés
Codemotion: descubriendo las cachés
 
Unit tesing y el mito de los 0 bugs
Unit tesing y el mito de los 0 bugsUnit tesing y el mito de los 0 bugs
Unit tesing y el mito de los 0 bugs
 
We Love Js 6 - Knockout js (with Marc Rubiño)
We Love Js 6 - Knockout js (with Marc Rubiño)We Love Js 6 - Knockout js (with Marc Rubiño)
We Love Js 6 - Knockout js (with Marc Rubiño)
 
Mobile services by @quiqu3
Mobile services by @quiqu3Mobile services by @quiqu3
Mobile services by @quiqu3
 
Javascript no es vietnam
Javascript no es vietnamJavascript no es vietnam
Javascript no es vietnam
 
Where is my beer?
Where is my beer?Where is my beer?
Where is my beer?
 
Coding kihon + Zombie Code Survival Guide
Coding kihon + Zombie Code Survival GuideCoding kihon + Zombie Code Survival Guide
Coding kihon + Zombie Code Survival Guide
 
Level up your skills
Level up your skillsLevel up your skills
Level up your skills
 

Último

Introduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxIntroduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxFIDO Alliance
 
الأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهالأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهMohamed Sweelam
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024Lorenzo Miniero
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!Memoori
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc
 
Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfalexjohnson7307
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewDianaGray10
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsLeah Henrickson
 
CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)Wonjun Hwang
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfdanishmna97
 
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxMasterG
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...FIDO Alliance
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Paige Cruz
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityVictorSzoltysek
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightSafe Software
 
Event-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream ProcessingEvent-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream ProcessingScyllaDB
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...panagenda
 
(Explainable) Data-Centric AI: what are you explaininhg, and to whom?
(Explainable) Data-Centric AI: what are you explaininhg, and to whom?(Explainable) Data-Centric AI: what are you explaininhg, and to whom?
(Explainable) Data-Centric AI: what are you explaininhg, and to whom?Paolo Missier
 

Último (20)

Introduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptxIntroduction to FIDO Authentication and Passkeys.pptx
Introduction to FIDO Authentication and Passkeys.pptx
 
الأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهالأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهله
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
 
Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdf
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overview
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
 
CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
 
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...Hyatt driving innovation and exceptional customer experiences with FIDO passw...
Hyatt driving innovation and exceptional customer experiences with FIDO passw...
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
 
ChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps ProductivityChatGPT and Beyond - Elevating DevOps Productivity
ChatGPT and Beyond - Elevating DevOps Productivity
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and Insight
 
Event-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream ProcessingEvent-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream Processing
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
 
(Explainable) Data-Centric AI: what are you explaininhg, and to whom?
(Explainable) Data-Centric AI: what are you explaininhg, and to whom?(Explainable) Data-Centric AI: what are you explaininhg, and to whom?
(Explainable) Data-Centric AI: what are you explaininhg, and to whom?
 

DotNet Conference: code smells

  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10. public void CalculateTotalPrice() { //calculates taxes var taxes = 0.0m; foreach (var product in this.productLines) { // ... taxes += product.Price / product.TaxesPercent * 100; } //calculates price var price = 0.0m; foreach (var product in this.productLines) { // ... price += product.Price * product.Unit; } this.TotalPrice = price + taxes; }
  • 11. public void CalculateTotalPrice() { var taxes = this.CalculateTaxes(); var price = this.CalculatePrice(); this.TotalPrice = price + taxes; } public decimal CalculateTaxes() { // ... return taxes; } public decimal CalculatePrice() { // ... return price; }
  • 12.
  • 13. public class User { // ... } public class Product { // ... } public class ProductLine { // ... } public class Order { // ... }
  • 14. public class Customer { private string name; private string lastName; private string streetType; private string streetName; private string streetNumber; private string floorNumber; private string doorNumber; private string postalCode; private string city; private string state; private string country; private string phone; private string email; }
  • 15. public class Customer { private string name; private string lastname; private string phone; private string email; private Address address; } public class Address { private string streetType; private string streetName; private string streetNumber; private string floorNumber; private string doorNumber; private string postalCode; private string city; private string state; private string country; }
  • 16. public void Draw(int x, int y, int width, int heigth, int borderSize, Color borderColor, Color backgroundColor) { // ... }
  • 17. public void Draw(BorderedRectangle rectangle) { // ... } public class Rectangle { public int X { get; set; } public int Y { get; set; } public int Width { get; set; } public int Height { get; set; } public Color Color { get; set; } } public class BorderedRectangle : Rectangle { public int BorderSize { get; set; } public Color BorderColor { get; set; } }
  • 18. class Rectangle { public void Draw(int x, int y, int width, int height, int borderSize, Color borderColor, Color backgroundColor) { this.DrawRectable(x, y, width, height, backgroundColor); this.DrawRectangleBorder(x, y, width, height, borderSize, borderColor); } private void DrawRectable(int x, int y, int width, int height, Color color) { // ... } private void DrawRectangleBorder(int x, int y, int width, int height, int borderSize, Color color) { // ... }
  • 19. public class Rectangle { public int X { get; set; } public int Y { get; set; } public int Width { get; set; } public int Height { get; set; } public Color Color { get; set; } public void Draw() { /* ... */ } } public class BorderedRectangle : Rectangle { public int BorderSize { get; set; } public Color BorderColor { get; set; } public void Draw() { base.Draw(); /* ... */ } }
  • 20. namespace MyTech { class MyTechConnection { } class MyTechConnectionHndl { } class Order { public bool Order(OrderRequest request) { /* ... */ } } class Inv { int Do(int a, string s, double d) { /* ... */ } } }
  • 21. namespace MyTechnology { class Connection { } class ConnectionHandler { } class OrderManager { public bool Request(Order order) { /* ... */ } } class Invoice { bool Pay(int userId, string account, double price) { /* ... */ } } }
  • 22.
  • 23. private const decimal USDolarChange = 1.13845m; private const decimal BritishPoundsChange = 0.739373275m; public enum MoneyTypes { Euro, USDolar, BritishPounds }; public decimal ConvertValue(decimal money, MoneyTypes type) { switch (type) { case MoneyTypes.Euro: return money; case MoneyTypes.USDolar: return money * USDolarChange; case MoneyTypes.BritishPounds: return money * BritishPoundsChange; default: return money; } }
  • 24. public class Euro { public decimal Value { get; set; } public virtual decimal GetConvertedValue() { return this.Value; } } public class USDolar : Euro { public override decimal GetConvertedValue() { return this.Value * USDolarChange; } } public class BritishPounds : Euro { public override decimal GetConvertedValue() { return this.Value * BritishPoundsChange; } }
  • 25. public decimal GetDiscount() { var basePrice = quantity * itemPrice; if (quantity > 1000) return basePrice * 0.95; else if (quantity > 500) return 20.0d; }
  • 26. public decimal GetDiscount() { if (quantity > 1000) return CalculateBasePrice() * 0.95; else if (quantity > 500) return 20.0d; } private decimal CalculateBasePrice() { return quantity * itemPrice; }
  • 27. abstract class Membership { public abstract IEnumerable<User> GetUsers(); public abstract IEnumerable<Profile> GetProfiles(); public abstract User Auth(string user, string password); public abstract IEnumerable<Profile> GetUserProfile(User user); } class MyMembership : Membership { public override IEnumerable<User> GetUsers() { throw new NotImplementedException(); } public override IEnumerable<Profile> GetProfiles() { throw new NotImplementedException(); } public override User Auth(string user, string password) { // ... } public override IEnumerable<Profile> GetUserProfile(User user) { // ... } } ¿Liskov?
  • 28. abstract class Membership { public abstract User Auth(string user, string password); public abstract IEnumerable<Profile> GetUserProfile(User user); } class MyMembership : Membership { public override User Auth(string user, string password) { // ... } public override IEnumerable<Profile> GetUserProfile(User user) { // ... } }
  • 29. class TokiotaService { // ... } class MicrosoftService { // ... } public IEnumerable<TokiotaItem> GetTokiotaItems() { return this.tokiotaService.GetProyects(); } public IEnumerable<MicrosoftItem> GetMicrosoftItems() { return this.microsoftService.GetPartnerCollaborations(); }
  • 30. class Item { /* ... */ } class IAdapter { IEnumerable<Item> GetItems(); } class MicrosoftAdapter : IAdapter { /* ... */ } class TokiotaAdapter : IAdapter { /* ... */ } public IEnumerable<Item> GetItems(IAdapter adapter) { return adapter.GetItems(); }
  • 31. public decimal CalculateTotalPrice() { if (this.isChristmas) { return this.CalculateChristmas(); } else { if (this.HasDiscount()) { return this.CalculateDiscounted(this.GetDiscount()); } else { if (this.isTimeOfSale) { return this.CalculateDiscounted(this.GetSalesDiscount()); } else { return this.CalculateStandard(); } } } }
  • 32. public decimal CalculateTotalPrice() { if (this.isChristmas) return this.CalculateChristmas(); if (this.HasDiscount()) return this.CalculateDiscounted(this.GetDiscount()); if (this.isTimeOfSale) return this.CalculateDiscounted(this.GetSalesDiscount()); return this.CalculateStandard(); }
  • 33.
  • 34. class Customer { public string Name { get; set; } public string LastName { get; set; } public string toXML() { return @"<Customer>" + "<Name>" + this.Name + "</Name>" + "<LastName>" + this.LastName + "</LastName>" + "</Customer>"; } } Open-Close?
  • 35. class Customer { private readonly CustomerXmlSerializer serializer = ...; public string Name { get; set; } public string LastName { get; set; } public string toXML() { return this.serializer.Serialize(this); } } class CustomerXmlSerializer : XmlSerializer { public string Serialize(Customer c) { var sb = new StringBuilder(); sb.Append(this.StartTag("Customer")); sb.Append(this.WriteTag("Name", c.Name)); sb.Append(this.WriteTag("LastName", c.LastName)); sb.Append(this.EndTag("Customer")); }
  • 36. class OrderManager { decimal CalculateOrderPrice(Product[] products, int[] units) { /* ... */ } } class OrderViewModel { public Product[] Products { get; set; } public int[] Units { get; set; } } class OrderService { void SendOrder(Product[] products, int[] units) { /* ... */ } } ¿Y si queremos añadir IVA?
  • 37. class Order { public Product[] Products { get; set; } public int[] Units { get; set; } public decimal GetPrice() { /* ... */ } } class OrderManager { decimal CalculateOrderPrice(Order order) { return order.GetPrice(); } } class OrderViewModel { public Order Order { get; set; } } class OrderService { void SendOrder(Order order) { /* ... */ } }
  • 38. class Vehicle { } class Car : Vehicle { } class Truck : Vehicle { } class Motorbike : Vehicle { } class VehicleXmlSerializer { } class CarXmlSerializer : VehicleXmlSerializer { } class TruckXmlSerializer : VehicleXmlSerializer { } class MotorbikeXmlSerializer : VehicleXmlSerializer { } Vehicle Class Car Truck Motorbike Xml Car Truck MotorBike
  • 39. class VehicleXmlSerializer { public VehicleXmlSerializer(IToXmlStrategy[] strategies) { } } interface IToXmlStrategy { } interface IToXmlStrategy<T> where T : Vehicle { } class CarToXmlStrategy : IToXmlStrategy<Car> { } class TruckTOXmlStrategy : IToXmlStrategy<Truck> { } class MotorbikeToXmlStrategy : IToXmlStrategy<Motorbike> { }
  • 40. class OrderViewModel { decimal CalculateTax() { return totalPrice * 0.21; } } class Invoice { decimal ShowTax() { return order.TotalPrice * 0.21; } } class ViewModel { public decimal Tax { get { return 21.0; } } }
  • 41. static class Globals { public const decimal TaxPercent = 21.0m; public const decimal TaxDelta = TaxPercent / 100; } class OrderViewModel { decimal CalculateTax() { return totalPrice * Globals.TaxDelta; } } class Invoice { decimal ShowTax() { return order.TotalPrice * Globals.TaxDelta; } } class ViewModel { public decimal Tax { get { return Globals.TaxPercent; } } }
  • 42.
  • 43. class LazyClass { public static string FormatName(string name, string lastname, string surname) { return string.Format("{1}, {0} ({2})", name, lastname, surname); } } Solo un método llamada desde solo un lugar
  • 44. class CustomerInfo { public string Name { get; set; } public string LastName { get; set; } public string Surname { get; set; } public override string ToString() { return string.Format("{1}, {0} ({2})", this.Name, this.LastName, this.Surname); } }
  • 45. class Settings { public string Name { get; set; } public string Host { get; set; } public bool UseSsl { get; set; } public int NumerOfConnections { get; set; } } class SettingsManager { public void Save(Settings settings) { /* ... */ } public Settings Load() { /* ... */ } } Una clase con las propiedades y otra con los métodos
  • 46. class Settings { public string Name { get; set; } public string Host { get; set; } public bool UseSsl { get; set; } public int NumerOfConnections { get; set; } public void Save() { /* ... */ } public void Load() { /* ... */ } }
  • 47. class MyClass { public int MyProperty { get; set; } public string Name { get; set; } public void Process() { /* ... */ } public void Send() { /* ... */ } } class MyClassOld { public string Name { get; set; } public void Process() { /* ... */ } }
  • 48. class MyClass { public int MyProperty { get; set; } public string Name { get; set; } public void Process() { /* ... */ } public void Send() { /* ... */ } }
  • 49. class CustomerController { public ActionResult Edit(Customer customer) { if (Model.IsValid) { this.customerRepository.InsertOrUpdate(customer); this.customerRepository.Save(); return RedirectToAction("Index"); } return View(); } } class EmployeeController { public ActionResult Edit(Employee employee) { if (Model.IsValid) { this.employeeRepository.InsertOrUpdate(employee); this.employeeRepository.Save(); return RedirectToAction("Index"); } return View(); } }
  • 50. class ControllerBase<TEntity> where TEntity : IEntity { IRepository<Employee> repository; public ActionResult Edit(TEntity entity) { if (Model.IsValid) { this.repository.InsertOrUpdate(entity); this.repository.Save(); return RedirectToAction("Index"); } return View(); } } class CustomerController : ControllerBase<Customer> { } class EmployeeController : ControllerBase<Employee> { }
  • 51. public interface ITextFormatStrategy { string Format(string input); } public class CommentTextFormatContext { private ITextFormatStrategy strategy; public CommentTextFormatContext(ITextFormatStrategy strategy) { this.strategy = strategy; } public int ExecuteStrategy(string input) { return strategy.Format(input); } } public class RemoveHtmlTagsStrategy : ITextFormatStrategy { public string Format(string input) { return Regex.Replace(input, @"<[^>]*>", string.Empty); } } ¿Solo una estrategia? YAGNI
  • 52. public class Comment { public void SetMessage(string message) { this.Text = Regex.Replace(message, @"<[^>]*>", string.Empty); } }
  • 53. // calculates the total price of the order public decimal Calculate() { // in christmas time if (DateTime.Now >= new DateTime(DateTime.Now.Year, 12, 25) && DateTime.Now <= new DateTime(DateTime.Now.Year + 1, 1, 5)) { // it has a discount of 10% return this.TotalPrice * 0.9; } else { return thisw.TotalPrice; } }
  • 54. public decimal CalculateOrderTotalPrice() { if (IsChirstmasTime()) { return this.ApplyDiscountPercentage(10); } else { return this.TotalPrice; } } private decimal ApplyDiscountPercentage(int percentage) { return this.TotalPrice * (100 - percentage) / 100; } private static bool IsChirstmasTime() { return DateTime.Now >= new DateTime(DateTime.Now.Year, 12, 25) && DateTime.Now <= new DateTime(DateTime.Now.Year + 1, 1, 5); }
  • 55.
  • 56. public class Product { public bool HasBeenOrdered(Order order) { return order.Products.Contains(this); } } public class Order { public List<Product> Products { get; set; } }
  • 57. public class Product { } public class Order { public List<Product> Products { get; set; } public bool HasBeenOrdered(Product product) { return this.Products.Contains(product); } }
  • 58. public class Customer { public string Name { get; set; } public string LastName { get; set; } public string PhoneNumber { get; set; } public string Address { get; set; } } public class Order { private Customer customer; public string GetSummary() { var summary = string.Format("{0} {1}n{2}n{3}", this.customer.Name, this.customer.LastName, this.customer.PhoneNumber, this.customer.Address); summary += "n" + this.TotalPrice + " €"; return summary; } }
  • 59. public class Customer { public string Name { get; set; } public string LastName { get; set; } public string PhoneNumber { get; set; } public string Address { get; set; } public override string ToString() { return string.Format("{0} {1}n{2}n{3}", this.Name, this.LastName, this.PhoneNumber, this.Address); } } public class Order { private Customer customer; public string GetSummary() { return this.customer.ToString() + "n" + this.TotalPrice + " €"; } }
  • 60. public decimal CalculateTotalPrice() { /* ... */ if (this.Customer.Address.Country.IsEuropean) { /* ... */ } /* ... */ }
  • 61. public decimal CalculateTotalPrice() { /* ... */ if (this.Customer.IsEuropean) { /* ... */ } /* ... */ } public class Customer { public bool IsEuropean { get { return this.Address.IsEuropean; } } }
  • 62. class MyConnection { private SqlConnection connection = new SqlConnection(); public string ConnectionString { get { return this.connection.ConnectionString; } } public void Open() { this.connection.Open(); } public MyCommand CreateCommand() { return new MyCommand(this.connection.CreateCommand()); } }
  • 63. SqlConnection connection = new SqlConnection();
  • 64. class XmlSerializer { public string StartTagString { get; set; } public string EndTagString { get; set; } public XmlSerializer() { StartTagString = "<{0}>"; EndTagString = "</{0}>"; } protected string WriteTag(string name, string value) { return StartTag(name) + value + EndTag(name); } protected string StartTag(string name) { return string.Format(StartTagString, name); } protected string EndTag(string name) { return string.Format(EndTagString, name); } }
  • 65. class XmlSerializer { private const string StartTagString = "<{0}>"; private const string EndTagString = "</{0}>"; protected string WriteTag(string name, string value) { return StartTag(name) + value + EndTag(name); } protected string StartTag(string name) { return string.Format(StartTagString, name); } protected string EndTag(string name) { return string.Format(EndTagString, name); } }
  • 66.
  • 67.
  • 68.
  • 69. Fernando Escolar @fernandoescolar fernando.escolar@tokiota.com ¡¡¡Si te ha gustado no olvides rellenar la encuesta!!! Thanks Y A X B

Notas del editor

  1. POO/OOP: es un paradigma de programación (como la programación funcional) que propone la creación de diferentes objetos reutilizables, que se popularizó en los años 90 y sus características son: Abstracción: implica la creación de objetos que indican un comportamiento. Por ejemplo una interfaz o una clase base. Encapsulamiento: cuando un objeto contiene todos los métodos y propiedades que comprenden un comportamiento de un tema en concreto, se dice que está encapsulado. Se le pueden añadir niveles de acceso. Herencia: Los objetos no se encuentran aislados, se pueden comunicar entre ellos y pueden formar una estructura jerárquica. Cohesión: significa que cuando encapsulemos el comportamiento, este tenga sentido sobre el mismo tema. Es decir que no mezclemos un objeto que sirva para escribir en consola y para realizar un cálculo complejo matemático. La cohesión añade sentido a la encapsulación. Poliformisfo: son comportamientos diferentes entre objetos distintos que comparten la misma firma: nombre y parámetros. El término “Technical Debt” (Deuda Técnica) fue introducido en 1992 por Ward Cunningham. Es una metáfora que viene a explicar que la falta de calidad en el código fuente de nuestro proyecto, genera una deuda que repercutirá en sobrecostes, tanto en el mantenimiento de un software, como en la propia operativa funcional de la aplicación. Cuando hablamos de un sobrecoste, puede significar desde tener que dedicarle más tiempo o más desarrolladores de los estimados, hasta acumular malestar general y mal ambiente.  SOLID: Que es el acrónimo de 5 principios. Single Responsibility: una clase o función solo debe tener una y solo una razón para existir o ser modificada. Open-Close: el código debe estar abierto a la extensión, pero cerrado a modificaciones. Liskov Substitution: las clases derivadas, deben poder ser sustituidas por su clase base. Interface Segregation: Desgranar las interfaces lo más fino posible, para que sean lo más específicas posible. Dependency Inversion: Hay que depender de las abstracciones no de las concreciones.
  2. En castellano “Code Smells” se traduce como “Olores de código”. Parece ser que fue Kent Beck quien acuñó este concepto a finales de la década de los 90. Pero no se popularizó hasta su aparición en el conocido libro de Martin Fowler: “Refactoring: improving the Design of Existing Code”. ¿Qué son? Los olores del código, son indicadores que señalan, por lo general, un problema más profundo: violaciones de los principios de diseño, con un impacto negativo en la calidad del desarrollo. ¿Qué es calidad? Podríamos decir muchas cosas acerca de la calidad: que tenga un buen diseño, que las métricas de código sean de un valor y otro, que r# no nos llame la atención, que… pero la mejor forma de definir la calidad del código es: “Programa siempre como si el tipo que mantendrá tu código fuera un psicópata violento que sabe donde vives.” - Martin Golding ¿Cómo lo soluciono? Refactoring: Es el proceso de mejorar la calidad del código fuente sin alterar su funcionalidad. Pero… no hay una receta mágica, solo guías. Es fundamental el criterio del desarrollador. Para aplicar los Refactorings se deben crear los Test necesarios para asegurarnos que no vamos a romper nada, y luego realizar los cambios paso a paso..
  3. Rigidez: Cuando algo es rígido significa que no se puede moldear. Un código rígido es aquel que resulta muy difícil de mantener y extender. Fragilidad: Si alguna vez te has encontrado con un programa que al cambiar un detalle, empieza a fallar en muchos puntos donde no has tocado nada, ya te has encontrado con código frágil. Un código que solemos tratar con miedo y bordeamos para modificarlo lo menos posible, generando así más código mal oliente. Inmovilidad: Aunque la solución tiene partes que serían interesantes en otros sistemas, el esfuerzo y riesgo de separarlas del resto del código es tan grande que nunca se reutilizan, se vuelven a escribir. Viscosidad: Podemos definir como viscoso un entorno de desarrollo que es lento e ineficiente. Pero también es viscoso aquel código que es más difícil de usar tal y como está diseñado. Por lo general preferiremos realizar unos “hacks” que programarlo como estaba pensado. Complejidad innecesaria: Contiene elementos muy complejos difíciles de identificar y entender su utilidad, artefactos y funciones que no se usan, y código que no es útil en absoluto. Repeticiones de código: la consecuencia de la maniobra informática más conocida del mundo: copiar y pegar. Crear código repetido a lo largo de toda la aplicación implica que no se ha conseguido identificar esas partes y agruparlas en funciones, clases y contextos comunes. Opacidad: Decimos que un objeto es opaco cuando no se puede ver a través de él. Es decir, un código que es difícil de entender y leer.
  4. The Bloaters: Agrupa smells que indican la existencia de algún aspecto que con el tiempo y el crecimiento pueden volver incontrolable el código. The Object Orientation Abusers: El común denominador de este tipo de smells es que representan casos donde la solución no explota completamente las posibilidades del diseño orientado a objetos. The Change Preventers: Estos smells dificultan la posibilidad de realizar cambios en nuestro software o de simplemente seguir avanzando en el desarrollo. Violan la regla sugerida por Fowler y Beck, que dice que las clases y los posibles cambios deben tener una relación de uno a uno. The Dispensables: Estos Smells tienen en común la existencia de algún elemento innecesario que debería ser eliminado del código fuente. The Couplers: Son smells que alertan sobre problemas en el manejo del acoplamiento entre componentes, pudiendo ser este excesivo y o mal diseñado.
  5. Los métodos largos son mas difíciles de leer, de entender y sobre todo de depurar. Mantener los métodos con pocas líneas ayuda a poder evitar este problema. Si ya tenemos métodos largos podemos considerar separarlos en métodos mas pequeños.
  6. Similar a los métodos largos también son difíciles de leer, entender y depurar. Además las clases grandes muestran otros problemas, como por ejemplo que una única clase contiene demasiadas responsabilidades.
  7. No utilizar una set de variables de tipos primitivos como un sustituto simple para una clase. Si el tipo de datos es lo suficientemente complejo, escribir una clase para que lo represente.
  8. Cuantos mas parámetros reciba un método mas complejo se vuelve de entender y utilizar. Para evitar esto podemos mantener la baja cantidad de parámetros que recibe un método o considerar crear una clase o estructura para pasar estos valores.
  9. Si siempre vemos que la misma información viaja todo el tiempo junta, es muy probable que esos datos sueltos pertenezcan a una misma clase. Considerar integrarlos en la clase que corresponda.
  10. Switchs o cualquier implementación oculta de switch (if, else, if…). Que podrían indicar una falta de utilización de mecanismos de herencia.
  11. El más simple es reemplazar las condiciones usando el polimorfismo. Pero otros refactoring para switch sería los patrones visitor, decorator, strategy, command…
  12. Estar atentos a los objetos que contenga muchos campos opcionales o innecesarios. Si estamos usando un objeto como parámetro de un método asegurarnos que se use todo de él.
  13. Si heredamos de una clase, pero no utilizamos ninguna funcionalidad, ¿para qué vamos a mantener esa herencia? Esto rompe el principio de sustitución de Liskov.
  14. Si dos clases son similares en el interior, pero difieren en el exterior, es probable que se puedan modificar para compartir una interfaz común.
  15. Tener cuidado al detectar o utilizar bloques condicionales muy largos, particularmente los que tienden a crecer con cada cambio que se introduce. Considerar una alternativa orientada a objetos como el uso de un patrón Decorator, Strategy, o State.
  16. Si a través del tiempo, los cambios en una clase necesitan que se toquen muchas partes diferentes de esta, es probable que la clase contenga funcionalidad que no esta relacionada. Considerar aislar las distintas partes en clases diferentes.
  17. Si un cambio en una clase requiere cambios en cascada en muchas otras clases, seguramente nos encontramos en una situación donde una funcionalidad esta mal distribuida.
  18. Cada vez que se realiza una subclase de una clase, se tiene que hacer una sublclase de otra. Considerar unir la jerarquía en una sola clase.
  19. Y también magic strings
  20. Si una clase hace poco y nada, debería eliminarse o combinarse con otra clase.
  21. Evitar clases que solamente almacenen información. Las clases deberían contener información y métodos para operar sobre esta.
  22. Eliminar código que no se utilice. Para eso tenemos sistemas de control de código fuente!
  23. El código duplicado es la peor anti-practica en el desarrollo de software. Eliminar la duplicación siempre que sea posible y estar siempre atento a los casos más sutiles de casi duplicación. DRY!!!
  24. El código que escribimos HOY tiene que ser para resolver los problemas que tenemos HOY. No nos preocupemos por el mañana. YAGNI you aint gonna need it
  25. Hay una línea muy fina entre los comentarios que iluminan y los que oscurecen. Son necesarios? Se puede refactorizar el código para no se necesiten?
  26. Comentar por qué y no el qué
  27. Métodos que realizan un uso extensivo de otra clase, probablemente deberían pertenecer a la otra clase. Deberíamos considerar mover estos métodos a la clase que corresponda.
  28. Estar atentos a las clases que pasan mucho tiempo juntas o que se comunican de modos inapropiados. Las clases deberían conocer lo menos posible unas de otras.
  29. Atentos a las secuencias de llamadas ,posiblemente entre clases, a métodos o variables temporales para obtener datos de rutina. Cualquier intermediario es una dependencia disfrazadas.
  30. Si una clase está delegando todo su trabajo, ¿para qué existe? Elimiar todos los intermediarios. Atencion a las clases que son meramente wrappers sin agregar funcionalidades al framework o contexto.
  31. Cuidado con las clases que exponen innecesariamente su interior. Refactorizar clases para minimizar su interfaz pública. Debe existir una razón de peso para que cada metodo, evento o propiedad que sea pública. Si no existe hay que ocultarlo.