Abu Dhabi Escorts Service 0508644382 Escorts in Abu Dhabi
DUMP-2015: «Как сменить язык программирования и не притащить старые привычки в новый мир» Алексей Могильников, Artec Group Inc
1. В презентации содержится 33 слайда с кодом, сцены насилия,
негуманного обращения с разработчиками и жестокого рефакторинга
Беременным женщинам, детям, лицам страдающим паранойей и
неспособностью воспринимать код, а также менеджерам
от просмотра рекомендуется воздержаться
18. public class Owner : IOwner
{
public Owner(string title, string castle, string words, Money initBalance)
{
Title = title;
Castle = castle;
Words = words;
Account = new Account(initBalance.Currency, initBalance.Amount);
}
public IAccount Account { get; set; }
public string Title { get; private set; }
public string Words { get; private set; }
public string Castle { get; private set; }
}
19. public class Account : IAccount
{
public Account(Currency currency, decimal initialBalance)
{
Id = Guid.NewGuid().ToString();
Currency = currency;
InitialBalance = initialBalance;
_transactions = new List<ITransaction>();
}
public string Id { get; private set; }
public Currency Currency { get; private set; }
public decimal InitialBalance { get; private set; }
private readonly List<ITransaction> _transactions;
public IEnumerable<ITransaction> Transactions
{
get { return _transactions; }
}
…
}
20. public class Account : IAccount
{
…
public void AddTransaction(ITransaction transaction)
{
if (_transactions.Any(t => t.Id == transaction.Id))
throw new ApplicationException("Hodor?");
if (transaction.Account != this)
throw new ApplicationException("Hodor!");
_transactions.Add(transaction);
}
public Money GetBalance()
{
var amount = InitialBalance +
_transactions.Sum(transaction => transaction.Amount);
return new Money(amount, Currency);
}
}
21. public class Transaction : ITransaction
{
public Transaction(IAccount account, decimal amount, string comment)
{
Id = Guid.NewGuid().ToString();
Comment = comment;
Amount = amount;
Account = account;
}
public string Id { get; private set; }
public IAccount Account { get; private set; }
public decimal Amount { get; private set; }
public ITransaction Reference { get; private set; }
public string Comment { get; private set; }
}
22. public class Money
{
public Money(decimal amount, Currency currency)
{
Amount = amount;
Currency = currency;
}
public decimal Amount { get; private set; }
public Currency Currency { get; private set; }
}
public enum Currency
{
Dragons,
Stags,
Groats,
Pennies
}
23. public void Show()
{
var starksInitMoney = new Money(1500, Currency.Stags);
var lannistersInitMoney = new Money(9999, Currency.Dragons);
var starks = new Owner("House Stark", "Winterfell", "Winter is Coming",
starksInitMoney);
var lannisters = new Owner("House Lannister", "Casterly Rock", "Hear Me Roar!",
lannistersInitMoney);
_receiptConsolePrinter.Print(starks);
_receiptConsolePrinter.Print(lannisters);
var money = new Money(100, Currency.Dragons);
_transferService.Transfer(starks.Account, lannisters.Account, money,
"Pwned by Lannisters");
_receiptConsolePrinter.Print(starks);
_receiptConsolePrinter.Print(lannisters);
}
24. public void Show()
{
var starksInitMoney = new Money(1500, Currency.Stags);
var lannistersInitMoney = new Money(9999, Currency.Dragons);
var starks = new Owner("House Stark", "Winterfell", "Winter is Coming",
starksInitMoney);
var lannisters = new Owner("House Lannister", "Casterly Rock", "Hear Me Roar!",
lannistersInitMoney);
_receiptConsolePrinter.Print(starks);
_receiptConsolePrinter.Print(lannisters);
var money = new Money(100, Currency.Dragons);
_transferService.Transfer(starks.Account, lannisters.Account, money,
"Pwned by Lannisters");
_receiptConsolePrinter.Print(starks);
_receiptConsolePrinter.Print(lannisters);
}
25. public class ReceiptConsolePrinter : IReceiptConsolePrinter
{
private readonly IKingsMentalStateCalculator _kingsMentalStateCalculator;
public ReceiptConsolePrinter(IKingsMentalStateCalculator kingsMentalStateCalculator)
{
_kingsMentalStateCalculator = kingsMentalStateCalculator;
}
public void Print(IOwner owner)
{
var balance = owner.Account.GetBalance();
Console.WriteLine("----------- RECEIPT -----------");
Console.WriteLine("Customer: {0} ({1})", owner.Title, owner.Words);
Console.WriteLine("Balance: {0} {1}", balance.Amount, balance.Currency);
Console.WriteLine("King's envy: {0}", _kingsMentalStateCalculator.GetEnvy(owner));
Console.WriteLine("-------------------------------");
Console.WriteLine();
}
}
26. public class ReceiptConsolePrinter : IReceiptConsolePrinter
{
private readonly IKingsMentalStateCalculator _kingsMentalStateCalculator;
public ReceiptConsolePrinter(IKingsMentalStateCalculator kingsMentalStateCalculator)
{
_kingsMentalStateCalculator = kingsMentalStateCalculator;
}
public void Print(IOwner owner)
{
var balance = owner.Account.GetBalance();
Console.WriteLine("----------- RECEIPT -----------");
Console.WriteLine("Customer: {0} ({1})", owner.Title, owner.Words);
Console.WriteLine("Balance: {0} {1}", balance.Amount, balance.Currency);
Console.WriteLine("King's envy: {0}", _kingsMentalStateCalculator.GetEnvy(owner));
Console.WriteLine("-------------------------------");
Console.WriteLine();
}
}
27. public class KingsMentalStateCalculator : IKingsMentalStateCalculator
{
private const decimal KingsEnvyThresholdGroats = 100;
private const decimal KingsGrace = 1000;
private readonly ICurrencyConverter _currencyConverter;
public KingsMentalStateCalculator(ICurrencyConverter currencyConverter)
{
_currencyConverter = currencyConverter;
}
public int GetEnvy(IOwner owner)
{
var balance = owner.Account.GetBalance();
var balanceInGroats = _currencyConverter.Convert(balance.Currency, Currency.Groats,
balance.Amount);
var incomesWithoutTrash = owner.Account.Transactions
.Select(t => _currencyConverter.Convert(owner.Account.Currency,Currency.Groats,
t.Amount))
.Where(amount => amount > KingsEnvyThresholdGroats);
var transactionsCountToEnvy = incomesWithoutTrash.Count();
if (transactionsCountToEnvy == 0) transactionsCountToEnvy = 1;
var envy = balanceInGroats/(transactionsCountToEnvy*KingsGrace);
return Convert.ToInt32(envy);
}
}
28. public class KingsMentalStateCalculator : IKingsMentalStateCalculator
{
private const decimal KingsEnvyThresholdGroats = 100;
private const decimal KingsGrace = 1000;
private readonly ICurrencyConverter _currencyConverter;
public KingsMentalStateCalculator(ICurrencyConverter currencyConverter)
{
_currencyConverter = currencyConverter;
}
public int GetEnvy(IOwner owner)
{
var balance = owner.Account.GetBalance();
var balanceInGroats = _currencyConverter.Convert(balance.Currency, Currency.Groats,
balance.Amount);
var incomesWithoutTrash = owner.Account.Transactions
.Select(t => _currencyConverter.Convert(owner.Account.Currency,Currency.Groats,
t.Amount))
.Where(amount => amount > KingsEnvyThresholdGroats);
var transactionsCountToEnvy = incomesWithoutTrash.Count();
if (transactionsCountToEnvy == 0) transactionsCountToEnvy = 1;
var envy = balanceInGroats/(transactionsCountToEnvy*KingsGrace);
return Convert.ToInt32(envy);
}
}
29. public class CurrencyConverter : ICurrencyConverter
{
private static readonly Dictionary<Currency, decimal> DragonExchangeRates =
new Dictionary<Currency, decimal>
{
{Currency.Dragons, 1m},
{Currency.Stags, 8.1m},
{Currency.Groats, 121.4m},
{Currency.Pennies, 268m},
};
public decimal Convert(Currency from, Currency to, decimal amount)
{
var fromRate = DragonExchangeRates[from];
var toRate = DragonExchangeRates[to];
return toRate*amount/fromRate;
}
}
30. public void Show()
{
var starksInitMoney = new Money(1500, Currency.Stags);
var lannistersInitMoney = new Money(9999, Currency.Dragons);
var starks = new Owner("House Stark", "Winterfell", "Winter is Coming",
starksInitMoney);
var lannisters = new Owner("House Lannister", "Casterly Rock", "Hear Me Roar!",
lannistersInitMoney);
_receiptConsolePrinter.Print(starks);
_receiptConsolePrinter.Print(lannisters);
var money = new Money(100, Currency.Dragons);
_transferService.Transfer(starks.Account, lannisters.Account, money,
"Pwned by Lannisters");
_receiptConsolePrinter.Print(starks);
_receiptConsolePrinter.Print(lannisters);
}
31. public class TransferService : ITransferService
{
private readonly ICurrencyConverter _currencyConverter;
public TransferService(ICurrencyConverter currencyConverter)
{
_currencyConverter = currencyConverter;
}
public void Transfer(IAccount from, IAccount to, Money money, string comment)
{
var minusAmount = _currencyConverter.Convert(money.Currency, from.Currency,
money.Amount);
var plusAmount = _currencyConverter.Convert(money.Currency, to.Currency,
money.Amount);
var t1 = new Transaction(from, -minusAmount, comment);
var t2 = new Transaction(to, plusAmount, comment);
from.AddTransaction(t1);
to.AddTransaction(t2);
}
}
32. public void Show()
{
var starksInitMoney = new Money(1500, Currency.Stags);
var lannistersInitMoney = new Money(9999, Currency.Dragons);
var starks = new Owner("House Stark", "Winterfell", "Winter is Coming",
starksInitMoney);
var lannisters = new Owner("House Lannister", "Casterly Rock", "Hear Me Roar!",
lannistersInitMoney);
_receiptConsolePrinter.Print(starks);
_receiptConsolePrinter.Print(lannisters);
var money = new Money(100, Currency.Dragons);
_transferService.Transfer(starks.Account, lannisters.Account, money,
"Pwned by Lannisters");
_receiptConsolePrinter.Print(starks);
_receiptConsolePrinter.Print(lannisters);
}
33. ----------- RECEIPT -----------
Customer: House Stark (Winter is Coming)
Balance: 1500 Stags
King's envy: 22
-------------------------------
----------- RECEIPT -----------
Customer: House Lannister (Hear Me Roar!)
Balance: 9999 Dragons
King's envy: 1214
-------------------------------
----------- RECEIPT -----------
Customer: House Stark (Winter is Coming)
Balance: 690.0 Stags
King's envy: 10
-------------------------------
----------- RECEIPT -----------
Customer: House Lannister (Hear Me Roar!)
Balance: 10099 Dragons
King's envy: 1226
-------------------------------
44. Герой
Ведь Ruby - это как C#,
только интерпретируемый и с
утиной типизацией!
45. class Owner
attr_reader :title, :castle, :words, :account
def initialize(title, castle, words, init_balance)
@title = title
@castle = castle
@words = words
@account = Account.new(init_balance.currency, init_balance.amount)
end
end
public class Owner : IOwner
{
public Owner(string title, string castle, string words, Money initBalance)
{
Title = title;
Castle = castle;
Words = words;
Account = new Account(initBalance.Currency, initBalance.Amount);
}
public IAccount Account { get; set; }
public string Title { get; private set; }
public string Words { get; private set; }
public string Castle { get; private set; }
}
46. class Account
attr_reader :id, :currency, :initial_balance, :transactions
def initialize(currency, initial_balance)
@id = SecureRandom.uuid
@currency = currency
@initial_balance = initial_balance
@transactions = []
end
…
end
public class Account : IAccount
{
public Account(Currency currency, decimal initialBalance)
{
Id = Guid.NewGuid().ToString();
Currency = currency;
InitialBalance = initialBalance;
_transactions = new List<ITransaction>();
}
public string Id { get; private set; }
public Currency Currency { get; private set; }
public decimal InitialBalance { get; private set; }
private readonly List<ITransaction> _transactions;
public IEnumerable<ITransaction> Transactions
{
get { return _transactions; }
}
…
}
47. public class Account : IAccount
{
…
public void AddTransaction(ITransaction transaction)
{
if (_transactions.Any(t => t.Id == transaction.Id))
throw new ApplicationException("Hodor?");
if (transaction.Account != this)
throw new ApplicationException("Hodor!");
_transactions.Add(transaction);
}
…
}
class Account
…
def add_transaction(transaction)
if @transactions.any? { |t| t.id == transaction.id }
raise StandardError.new("Hodor?")
end
if transaction.account != self
raise StandardError.new("Hodor!")
end
@transactions.push(transaction)
end
…
end
48. public class Account : IAccount
{
…
public Money GetBalance()
{
var amount = InitialBalance + _transactions.Sum(transaction => transaction.Amount);
return new Money(amount, Currency);
}
}
class Account
…
def get_balance
amount = initial_balance + transactions.sum { |t| t.amount }
return Money.new(amount, currency)
end
end
49. public class Transaction : ITransaction
{
public Transaction(IAccount account, decimal amount, string comment)
{
Id = Guid.NewGuid().ToString();
Comment = comment;
Amount = amount;
Account = account;
}
public string Id { get; private set; }
public IAccount Account { get; private set; }
public decimal Amount { get; private set; }
public ITransaction Reference { get; private set; }
public string Comment { get; private set; }
}
class Transaction
attr_reader :id, :account, :amount, :reference, :comment
def initialize(account, amount, comment)
@id = SecureRandom.uuid
@comment = comment
@amount = amount
@account = account
end
end
50. public class Money
{
public Money(decimal amount, Currency currency)
{
Amount = amount;
Currency = currency;
}
public decimal Amount { get; private set; }
public Currency Currency { get; private set; }
}
class Money
attr_reader :amount, :currency
def initialize(amount, currency)
@amount = amount
@currency = currency
end
end
52. public void Show()
{
var starksInitMoney = new Money(1500, Currency.Stags);
var lannistersInitMoney = new Money(9999, Currency.Dragons);
var starks = new Owner("House Stark", "Winterfell", "Winter is Coming",
starksInitMoney);
var lannisters = new Owner("House Lannister", "Casterly Rock", "Hear Me Roar!",
lannistersInitMoney);
…
}
def show
starks_init_money = Money.new(1500, Currency::STAGS)
lannisters_init_money = Money.new(9999, Currency::DRAGONS)
starks = Owner.new("House Stark", "Winterfell",
"Winter is Coming", starks_init_money)
lannisters = Owner.new("House Lannister", "Casterly Rock",
"Hear Me Roar!", lannisters_init_money)
…
end
53. public void Show()
{
…
_receiptConsolePrinter.Print(starks);
_receiptConsolePrinter.Print(lannisters);
var money = new Money(100, Currency.Dragons);
_transferService.Transfer(starks.Account, lannisters.Account, money,
"Pwned by Lannisters");
_receiptConsolePrinter.Print(starks);
_receiptConsolePrinter.Print(lannisters);
}
def show
…
@receipt_console_printer.print(starks)
@receipt_console_printer.print(lannisters)
money = Money.new(100, Currency::DRAGONS)
@transfer_service.transfer(starks.account, lannisters.account, money,
"Pwned by Lannisters")
@receipt_console_printer.print(starks)
@receipt_console_printer.print(lannisters)
end
71. Какой менталитет у Ruby
I hope to see Ruby help every programmer in the world to be productive,
and to enjoy programming, and to be happy.
That is the primary purpose of Ruby language.
Matz
72. Какой менталитет у Ruby
Акцент на
скорость разработки
и высокую читаемость кода
80. №1: миксины
module SharedCode
def say_hello
puts "Hello, my name is #{self.class.name}!"
end
end
class Vasya
include SharedCode
end
class Petya
include SharedCode
end
class Dyatel
end
Vasya.new.say_hello # => "Hello, my name is Vasya!"
Petya.new.say_hello # => "Hello, my name is Petya!"
Dyatel.new.say_hello # => NoMethodError: undefined method
81. №2: метапрограммирование
class Demo
# Read fields list from DB
[:name, :phone, :age].each do |field|
define_method "find_by_#{field}" do |value|
puts "Search for field '#{field}' with value '#{value}'"
end
end
end
demo = Demo.new
demo.find_by_name "Vasya" # => Search for field 'name' with value 'Vasya'
demo.find_by_age 14 # => Search for field 'age' with value '14'
87. class Demo
include ReceiptConsolePrinter
include TransferService
def show
starks_init_money = Money.new 1500, Currency::STAGS
lannisters_init_money = Money.new 9999, Currency::DRAGONS
starks = Owner.new "House Stark", "Winterfell", "Winter is Coming",
starks_init_money
lannisters = Owner.new "House Lannister", "Casterly Rock", "Hear Me Roar!»,
lannisters_init_money
print_receipt_for starks
print_receipt_for lannisters
money = Money.new 100, Currency::DRAGONS
transfer starks.account, lannisters.account, money, "Pwned by Lannisters"
print_receipt_for starks
print_receipt_for lannisters
end
end
88. Создавай объекты стильно!
module Demo
module MoneyMethods
CurrencyConverter::RATES.keys.each do |currency_name|
define_method currency_name.to_s do
Money.new self, currency_name
end
end
end
end
class Float
include Demo::MoneyMethods
end
class Fixnum
include Demo::MoneyMethods
end
89. class Demo
include ReceiptConsolePrinter
include TransferService
def show
starks = Owner.new "House Stark", "Winterfell", "Winter is Coming",
1500.stags
lannisters = Owner.new "House Lannister", "Casterly Rock",
"Hear Me Roar!", 9999.dragons
print_receipt_for starks
print_receipt_for lannisters
transfer starks.account, lannisters.account, 100.dragons, "Pwned by Lannisters"
print_receipt_for starks
print_receipt_for lannisters
end
end
90. И напиши уже тесты!
Роскомнадзор потребовал
удалить код, разжигающий ненависть по
отношению к тестам, написанным не на
динамических языках
91. Так как учить новые языки?
№1
Разберитесь в менталитете
языка
Найдите статью
92. Так как учить новые языки?
№2
Выполните упражнения
Есть для множества языков
93. Так как учить новые языки?
№3
Посмотрите код какого-нибудь
проекта
Небольшого, берегите мозг
94. Так как учить новые языки?
№4
Портируйте свой код
Покажите его кому-нибудь