- PVSM.RU - https://www.pvsm.ru -
Начало Код с душком [1]
Техника: Составление методов [2]
В продолжении, техника рефакторинга по книге Рефакторинг. Улучшение существующего кода Мартин Фаулер. [3]
Синтаксис будет на C#, но главное понимать идею, а её можно использовать в любом другом языке программирования.
class View
{
private Shop shop;
private List<User> FilterUsers(List<User> users, decimal koef)
{
List<User> activeUsers = new List<User>();
foreach(User user in users)
{
if(shop.IsActiveUser(user, koef))
{
activeUsers.Add(user);
}
}
return activeUsers;
}
}
class Shop
{
public bool IsActiveUser(User user, decimal koef)
{
decimal rate = 1;
if(koef > 1000)
{
rate = koef * 1.75;
}
return user.Boss || user.HasDiscount() && rate > 10;
}
}
class User
{
private bool boss;
public bool Boss
{
get { return boss; }
}
public bool HasDiscount()
{
// some condition
}
}
To
class View
{
private Shop shop;
private List<User> FilterUsers(List<User> users, decimal koef)
{
List<User> activeUsers = new List<User>();
foreach(User user in users)
{
if(user.IsActiveUser(koef))
{
activeUsers.Add(user);
}
}
return activeUsers;
}
}
class Shop
{
}
class User
{
private bool boss;
public bool Boss
{
get { return boss; }
}
public bool HasDiscount()
{
// some condition
}
public bool IsActiveUser(decimal koef)
{
decimal rate = 1;
if(koef > 1000)
{
rate = koef * 1,75;
}
return Boss || HasDiscount() && rate > 10;
}
}
class Shop
{
private decimal rate;
private DiscountType discountType;
public Shop(DiscountType discountType, decimal rate)
{
this.rate = rate;
this.discountType = discountType;
}
public decimal Rate
{
get{ return rate; }
set{ rate = value; }
}
public bool HasDiscount(DateTime from, DateTime to)
{
// some calculation of flag
return discountType.IsValid(rate) && flag;
}
public decimal GetDiscount(decimal amount, bool fullSum)
{
// some calculation of koef
return discountType.GetAmount(rate, fullSum) * koef;
}
}
class DiscountType
{
public bool IsValid(decimal rate)
{
// some calculation using rate
}
public decimal GetAmount(decimal rate, bool fullSum)
{
// some calculation using rate
}
}
To
class Shop
{
private DiscountType discountType;
public Shop(DiscountType discountType)
{
this.discountType = discountType;
}
public bool HasDiscount(DateTime from, DateTime to)
{
// some calculation of flag
return discountType.IsValid() && flag;
}
public decimal GetDiscount(decimal amount, bool fullSum)
{
// some calculation of koef
return discountType.GetAmount() * koef;
}
}
class DiscountType
{
private decimal rate;
public DiscountType(decimal rate)
{
this.rate = rate;
}
public decimal Rate
{
get{ return rate; }
set{ rate = value; }
}
public bool IsValid()
{
// some calculation using rate
}
public decimal GetAmount(bool fullSum)
{
// some calculation using rate
}
}
class User
{
private string name;
private string street;
private string city;
public string Name
{
get{ return name; }
set{ name = value; }
}
public string Street
{
get{ return street; }
set{ city = value; }
}
public string City
{
get{ return city; }
set{ city = value; }
}
public string GetAddressInfo()
{
return string.Format("{0} {1}", city, street);
}
}
To
class User
{
private string name;
private Address address;
public string Name
{
get{ return name; }
set{ name = value; }
}
public string GetAddressInfo()
{
return address.GetFullAddress();
}
}
class Address
{
private string city;
private string street;
public string Street
{
get{ return street; }
set{ city = value; }
}
public string City
{
get{ return city; }
set{ city = value; }
}
public string GetFullAddress()
{
return string.Format("Adress: {0} {1}", city, street);
}
}
class User
{
private string name;
private Address address;
public string Name
{
get{ return name; }
set{ name = value; }
}
public Address GetAddress()
{
return address
}
}
class Address
{
private string areaCode;
private string country;
public string AreaCode
{
get{ return areaCode; }
set{ areaCode = value; }
}
public string Country
{
get{ return country; }
set{ country = value; }
}
}
To
class User
{
private string name;
private string areaCode;
private string country;
public string AreaCode
{
get{ return areaCode; }
set{ areaCode = value; }
}
public string Country
{
get{ return country; }
set{ country = value; }
}
public string Name
{
get{ return name; }
set{ name = value; }
}
}
class View
{
private void Init()
{
// some code
User manager = currentUser.Office.Manager;
}
}
class User
{
private Department department;
public Department Office
{
get{ return department; }
set{ department = value; }
}
}
class Department
{
private User manager;
public Department(User manager)
{
this.manager = manager;
}
public User Manager
{
get{ return manager; }
}
}
To
class View
{
private void Init()
{
// some code
User manager = currentUser.Manager;
}
}
class User
{
private Department department;
public User Manager
{
get{ return department.Manager; }
}
}
class Department
{
private User manager;
public Department(User manager)
{
this.manager = manager;
}
public User Manager
{
get{ return manager; }
}
}
class View
{
private void Init()
{
// some code
User manager = currentUser.Manager;
decimal rate = currentUser.Rate;
}
}
class User
{
private Department department;
private UserType userType;
public User Manager
{
get{ return department.Manager; }
}
public decimal Rate
{
get{ return userType.Rate; }
}
}
class Department
{
private User manager;
public User Manager
{
get{ return manager; }
}
}
class UserType
{
private decimal rate;
public decimal Rate
{
get{ return rate; }
}
}
To
class View
{
private void Init()
{
// some code
User manager = currentUser.Office.Manager;
decimal rate = currentUser.Type.Rate;
}
}
class User
{
private Department department;
private UserType userType;
public Department Office
{
get{ return department; }
}
public UserType Type
{
get{ return userType; }
}
}
class Department
{
private User manager;
public User Manager
{
get{ return manager; }
}
}
class UserType
{
private decimal rate;
public decimal Rate
{
get{ return rate; }
}
}
class View
{
private string GetUserName()
{
// some code
return """ + userName + """;
}
private string GetCompanyName()
{
// some code
return """ + companyName + """;
}
}
To
class View
{
private string GetUserName()
{
// some code
return userName.InDoubleQuote();
}
private string GetCompanyName()
{
// some code
return companyName.InDoubleQuote();
}
}
static class StringExtension
{
public static string InDoubleQuote(this string str)
{
return """ + str + """;
}
}
sealed class Account
{
public decimal CalculateSum()
{
// calculation summ
return summ;
}
}
To
class ImportantAccount
{
private Account account;
public decimal CalculateMaxSum()
{
// calculation rate
return account.CalculateSum() * rate;
}
}
Как правило, всё споры/разногласия возникающие между review-ером и comitt-ерром можно разделить на следующие:
// если операнд с правой стороны, однозначно трактует возвращаемый тип, то можно использовать var
var users = new List<User>();
var departments = user.Departmens.Cast<Department>();
// плохо
var users = departments.Select(d => d.User).Where(u => !u.Deleted);
var departments = service.GetNotDeletedDepartments();
Забавные случаи:
1) Review-ер — «необходимо поправить код»
Commiter — «тебе не нравится ты и правь»/«ты нашёл ты и исправляй»
2) Или как правильно
void Method()
{
...
if(flag)
koef = GetMaxRate();
...
}
или
void Method()
{
...
if(flag)
{
koef = GetMaxRate();
}
...
}
Надеюсь продолжить и дальше «Техника: Организация данных».
Автор: den_labs
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/shpargalka/31970
Ссылки в тексте:
[1] Код с душком: http://habrahabr.ru/post/169139/
[2] Составление методов: http://habrahabr.ru/post/173903/
[3] Рефакторинг. Улучшение существующего кода Мартин Фаулер.: http://www.ozon.ru/context/detail/id/1308678/
[4] Источник: http://habrahabr.ru/post/174779/
Нажмите здесь для печати.