Если вы обновляете код с 0,6 до 1,0, сначала перейдите к 0,7. Это буквально точно так же, как 1.0 , но с дружественными предупреждениями, которые говорят вам, как обновить ваш код! И да, в этом случае вам будет предложено использовать @distributed
вместо @parallel
и загрузить распределенную стандартную библиотеку.
julia> @sync @parallel for i in 1:100;
V[i] = i
end
WARNING: Base.@parallel is deprecated: it has been moved to the standard library package `Distributed`.
Add `using Distributed` to your imports.
in module Main
┌ Warning: `@parallel` is deprecated, use `@distributed` instead.
│ caller = eval(::Module, ::Any) at boot.jl:319
└ @ Core ./boot.jl:319
Это было просто переименование и переименование по уважительной причине: существует много форм параллелизма, и «наиболее эффективная» форма параллелизма для вас будет зависеть от того, какую задачу вы выполняете (в частности время выполнения и IO) и имеющееся у вас оборудование.
Я думаю, что это распространенный случай злоупотребления паттернами.
Если вы проверите свои две «стратегии», они делают ТОЧНО одно и то же. Единственное, что меняется, это ProvincialTaxRate.
Я бы оставил вещи СУХИМЫМИ и не использовал бы этот шаблон (или любой другой) чрезмерно, здесь вы получаете немного гибкости, но тогда у вас также есть 2 класса, которые не тяготят, и, вероятно, вам не понадобится такая гибкость.
Это часто встречается, когда вы изучаете новую технологию или проницательность, вы хотите применять ее везде (это происходит с каждым из нас), даже если это наносит вред читабельности и удобству сопровождения кода.
Мое мнение: не усложняйте
С уважением
РЕДАКТИРОВАТЬ (В ответ на комментарий автора моего ответа)
Я не пытался высмеивать тебя или кого-либо. Это распространенная ошибка, я делал это МНОГИЕ раз и выучил ее нелегко, не только с шаблонами, но и с модными фреймворками, серверами, новыми технологиями модных слов, и так далее.
Авторы книги сами предупреждают читатели не должны чрезмерно использовать шаблоны, и возражения в этом ответе явно указывают на что-то тоже.
Но если по какой-то причине вы все еще хотите реализовать шаблон, вот мое скромное мнение:
Сделайте суперкласс для обеих стратегий, этот суперкласс будет абстрактным и должен содержать значение общей скорости их дочерних стратегий (FederalTaxRate)
Унаследовать и реализовать абстрактный метод «Вычислить» в каждом подклассе (здесь вы увидите, что оба метода одинаковы, но давайте продолжим)
Постарайтесь сделать каждую конкретную стратегию неизменной, всегда отдавайте предпочтение неизменности, как говорит Джошуа Блох. Для этого, Вот пример с некоторым (псевдо) кодом, чтобы сделать решение немного более понятным
Надеюсь, это поможет
С уважением
На мой взгляд, у вас есть правильное решение - создать базовый класс, который содержит канадский федеральный тариф на факс, с которого все ваших производных классов могут наследовать. Статически определять это - прекрасная идея. Вы также можете сделать так, чтобы FederalTaxRate определял только функцию доступа к налоговой ставке, чтобы вы могли определить ее во время выполнения из файла или чего-то еще.
Я не думаю, что это однозначно лучшее решение, но оно будет работать отлично. Шаблоны проектирования не должны мешать вашему здравому смыслу, и я думаю, что здравый смысл прекрасно решит эту проблему.
Возможно, вы захотите начать с этого кода и двигаться дальше:
public interface ITax
{
decimal CalculateTax(decimal subtotal);
}
public class SaskatchewanTax : ITax
{
private readonly decimal provincialTaxRate;
private readonly decimal federalTaxRate;
public SaskatchewanTax(decimal federalTaxRate)
{
provincialTaxRate = 0.05m;
this.federalTaxRate = federalTaxRate;
}
public decimal CalculateTax(decimal subtotal)
{
return provincialTaxRate * subtotal + federalTaxRate * subtotal;
}
}
public class OntarioTax : ITax
{
private readonly decimal provincialTaxRate;
private readonly decimal federalTaxRate;
public OntarioTax(decimal federalTaxRate)
{
provincialTaxRate = 0.08m;
this.federalTaxRate = federalTaxRate;
}
public decimal CalculateTax(decimal subtotal)
{
return provincialTaxRate * subtotal + federalTaxRate * subtotal;
}
}
В этот момент может не быть Было бы целесообразно иметь два разных объекта стратегии, представляющих расчет налога, но с более реалистичной реализацией (я предполагаю, что расчет налога более сложен и варьируется в зависимости от провинции).
Однако вам следует рассмотреть возможность применения принцип «простейшая вещь, которая могла бы работать», и использовать шаблон стратегии только тогда, когда вы чувствуете, что он необходим.
Почему бы вам не забыть об интерфейсах и просто использовать наследование для того, что вы можете:
public abstract class Tax
{
protected decimal ProvincialTaxRate; // Yes, you are Canadian ;)
public decimal CalculateTax(decimal subtotal)
{
return ProvincialTaxRate * subtotal + FederalTaxRate * subtotal;
}
decimal FederalTaxRate = new decimal(0.20f);
}
public class SaskatchewanTax : Tax
{
public SaskatchewanTax()
{
base.ProvincialTaxRate = new decimal(0.05f);
}
}
public class OntarioTax : Tax
{
public OntarioTax()
{
base.ProvincialTaxRate = new decimal(0.08f);
}
}
Если вам нужно интерфейс, просто реализуйте его в базовом классе и просто используйте производные классы для пользовательского поведения / поведения.
Несколько моментов:
ProvincialTaxRate
почти наверняка должен быть неизменным на уровне интерфейса (нет ] установить свойство
). Изменение налоговых ставок не кажется хорошей идеей, хотя это означает, что вы не можете использовать автоматические свойства в своей реализации.
Если есть только один FederalTaxRate
и это просто простое числовое значение Я думаю, что абстрактный базовый класс является безопасным подходом.
Менее целесообразно: в зависимости от того, как работают налоги, можно утверждать, что CalculateTax
зависит от FederalTaxRate
, и поэтому это необходимо предоставляется в качестве параметра (возможно, существуют разные FederalTaxRates
, и вы не хотите, чтобы CalculateTax
знал о них).
Don ' Позвольте определению шаблона проектирования помешать хорошей идее. Это шаблоны, а не формулы. ;)
PS Я американец, поэтому, если канадские налоги на самом деле так просты, я надеюсь, что IRS возьмет страницу из вашей книги в следующем году!
Просто пища для размышлений - что плохого в том, чтобы поместить этот метод в соответствующий класс и просто вызвать его?
public decimal CalculateTax(decimal subtotal, decimal provincialTaxRate, decimal federalTaxRate) {
return provincialTaxRate * subtotal + federalTaxRate * subtotal;
}
Я понимаю, что вы захотите использовать другой провинциальный ставка для каждой провинции, но неужели это не должно быть жестко закодировано в реализации интерфейса?