что такое режим состояния
Поведение объекта зависит от его состояния (атрибутов), что позволяет объекту изменять свое внутреннее состояние и связанное с ним поведение в соответствии с изменением своего состояния.
Режим состояния очень похож на режим стратегии, он также инкапсулирует «состояние» класса и выполняет автоматические переходы при выполнении действий, чтобы понять, что одно и то же действие класса в разных состояниях дает разные результаты. Разница между ним и режимом стратегии заключается в том, что это преобразование является «автоматическим» и «бессознательным». Режим стратегии заключается в поиске нескольких решений одной и той же проблемы, и эти разные решения не имеют никакого отношения; режим Требуется, чтобы существовала связь между различными состояниями для достижения перехода между состояниями.
текст
Когда я вернулся с Национального дня, я решил провести рефакторинг важных проектов нашей компании.Из-за его сложной логики я не мог найти хороший угол, чтобы разобраться в коде.Однажды ночью, когда ночь была темной и ветреной, я пришел в kfc. Когда я увидел ослепительный контент в меню, я задумался...
Вот формальный код, не вникайте в него
此时一份点单的内心独白
if (我的钱>50) {
if (饿) {
我好富有啊随便点,点2个我最喜欢的原味鸡,再来个套餐
} else {
自己喜欢的单品都来一样好了
}
} else if (30<我的钱<50) {
if (饿) {
低于50的套餐
} else {
自己喜欢的单品累加不能超过50
}
} else if (15<我的钱<30) {
if (饿){
低于30的套餐
}else{
自己喜欢的单品累加不能超过30
}
......
} else if (5<我的钱<15) {
只能根据价格来不能追求喜好了..
} else {
做洗碗工 || 饿肚子
}
В случае изменения суммы денег или цены на еду (статус)
1. Необходимо изменить условия покупки: возможно, потребуется переписать условия оценки кода.
2. Необходимо углубиться в условия покупок: добавление условий на более глубокий уровень становится сложным и утомительным.
Дебют режима статуса
Шаг 1: выйти из состояния
Шаблон состояния сначала должен суммировать элементы, которые будут влиять на поведение.
Мы перечисляем текущее состояние и оборачиваем его объектом состояния:
{
hungry: true/false,
money: 40,
single: [ 原味鸡, 鸡米花, 土豆泥, 薯条,汉堡...],
setMeal:[ 高调奢华套餐(50¥)、性价比套餐(40¥)、不管饱套餐(25¥) ],
}
Советы: в реальном бизнесе можно использовать различные интеллект-карты для обобщения состояния текущих потребностей.
Шаг 2: Планирование таблицы конфигурации
Инкапсулируйте взаимосвязь между состоянием и поведением в таблице и управляйте поведением посредством изменений состояния.
В соответствии с текущим состоянием конфигурационная таблица вариантов покупки суммируется:
抽象出俩个单位即手上的钱和自身饥饿情况,同时他们都有自己的触发条件,也就是不同的状态。
{
money: {
money> 50: [...single, ...setMeal], // 喜爱的单品和套餐都能选择
30 < money < 50: [...single, setMeal[0], setMeal[1]], // 价格允许的套餐和所有单品
15 < money < 30: [...single, setMeal[2]], // 价格允许的套餐和所有单品
5 < money < 15: [single[1], single[2], single[3]],// 价格允许的单品
money < 5: 做洗碗工 || 饿肚子,
},
hungry: true / false, //饿就选套餐/不饿选择单品
}
最后的购买行为:当前金钱数量决策出对应价位的菜品,再根据饥饿情况选出套餐还是单品组合
Мы можем понимать таблицу конфигурации как конечный автомат.Согласно изменению состояния, я могу повлиять на свое покупательское поведение.Если состояние (деньги) изменится (купоны, 50 юаней, найденные на земле...), также могу совершать предсказуемые покупки Действие (в конце концов, поведение было разделено в зависимости от количества денег).
Таблица конфигурации может больше фокусироваться на изменениях состояния при аварийном восстановлении кода или последующем обслуживании несколькими людьми.
Третий шаг (расширение): разделение на меньшую гранулярность
Добавить спрос: на кухне сказали, что оригинальная курица распродана и нужны только цветы с курицей и рисом, и необходимо разместить уведомление, а оригинальную курицу в наборе необходимо заменить на цветы с курицей и рисом.
Что касается детализации разделенной конфигурации, внимательно рассмотрите влияние внешних факторов на продукты питания, что приводит к изменениям в покупательском поведении, и возможность реконфигурации поведения в настраиваемый контент управления. Почему kfc — это блюдо и контейнер?
single: [ 原味鸡, 鸡米花, 土豆泥, 薯条,汉堡...],
setMeal:[ 高调奢华套餐(50¥)、性价比套餐(40¥)、不一定管饱套餐(25¥) ],
改造一下整体结构,每一个单品都有它的状态,方便我们根据状态组合(万一需求又改了呢?)
single: [
// 想想为什么我要多加价格,万一之后售价(需求)变动了呢?
{
name:原味鸡,
price:12,
stock:false, // 没货啦
},
{ name:鸡米花,
price:10,
stock:true,
},
....
....
....
],
setMeal:[
// 把菜单和单品之间的联系挂起来
{
name:高调奢华套餐:
price:50,
single[0], //原味鸡
single[1], //鸡米花
single[2], //土豆泥
single[3], //薯条
single[4] //汉堡
},{
name:性价比套餐,
price:40,
.... // 单品组合
}{
name:不管饱套餐
price:25
.... // 单品组合
} ],
Полные требования: Таким образом, вы можете напрямую заменить оригинальную курицу куриным попкорном.
now: single[0] = single[1]
кейс
В проекте, который мне нужно рефакторить, много разных блоков. Часть содержимого форм, которые они отображают, одинакова, а часть отличается. В настоящее время я могу настроить его через режим состояния.
Оригинальный код:
<el-form-item label="应用名称">
<el-input v-model="form.name"/>
</el-form-item>
<el-form-item label="发部分支">
<el-input v-model="form.branch"/>
</el-form-item>
<el-form-item v-if="env" label="发布环境">
<el-input v-model="form.env"/>
</el-form-item>
<el-form-item v-if="appType==='node'|| appType==='static'" label="npm install">
<el-input v-model="form.npm"/>
</el-form-item>
<el-form-item v-if="appType==='android'" label="打包加固">
<el-input v-model="form.package"/>
</el-form-item>
<el-form-item v-if="appType!=='static'&& env!='dev'" label="发布暂停">
<el-input v-model="form.isStop"/>
</el-form-item>
..... // 省略各种条件
Улучшенный код:
1.抽取状态:
环境:env:['prod', 'dev', 'test'], 应用:appType:['node','android','static']
2.配置状态机:
// configState.js
const configState = {
env:{
env:['env','dev','test'],
appType:['node','android','static'],
},
npm:{
env:['env'],
appType:['node','static'],
},
package:{
env:['env','dev','test'],
appType:['android'],
},
isStop:{
env:['env','test'],
appType:['android','node'],
},
}
3.抽象行为:
import { configState } from "./configState";
// 抽象当前展示行为
const state = fn(env, appType) {
/*
* 此处代码省略!!!
* 遍历configState,若env和appType数组中均含有则为true
*/
return {
env:true,
npm:true,
package:false,
isStop:true,
},
}
<el-form-item label="应用名称">
<el-input v-model="form.name"/>
</el-form-item>
<el-form-item label="发部分支">
<el-input v-model="form.branch"/>
</el-form-item>
<el-form-item v-if="state.env" label="发布环境">
<el-input v-model="form.env"/>
</el-form-item>
<el-form-item v-if="state.npm" label="npm install">
<el-input v-model="form.npm"/>
</el-form-item>
<el-form-item v-if="state.package" label="打包加固">
<el-input v-model="form.package"/>
</el-form-item>
<el-form-item v-if="state.isStop" label="发布暂停">
<el-input v-model="form.isStop"/>
</el-form-item>
Суммировать
Сцены
- Код содержит множество условных операторов, связанных с состоянием объекта, таких как if...else, switch..case и т. д.
- Путаница между логиками далеко друг от друга, и ее нужно абстрагировать и управлять ею в одном месте.
- Условия бизнеса часто меняются (программисты не берут на себя вину)
преимущество:
-
При изменении или увеличении сцены логика переключения состояний распределяется по классам состояний.Добавляя новые классы состояний, легко добавлять новые состояния и переходы.
-
Разделение, поведение в классах состояний и действий могут легко изменяться независимо друг от друга, не влияя друг на друга.
-
Сплоченность, наличие государственной машины позволяет больше сосредоточиться на управлении государством.
недостаток:
-
Существует столько одноэлементных методов, сколько и состояний, что создает много связанного поведения.
-
Структура кода становится сложной, и необходимо предоставить специальный файл конечного автомата.
выполнить
-
Сущностная модель государства-владельца.
-
Интерфейс состояния (можно также использовать абстрактные классы), определяющий бизнес-методы.
-
Каждый конкретный класс реализации состояния соответственно реализует бизнес-методы.
Ключ заключается в связи абстрактного состояния и поведения, обобщающей изменяемый и изменяемый код.
Все шаблоны проектирования имеют место в жизни,life is design
В конце концов, меня выгнала кассирша, потому что я был слишком испачкан чернилами и ничего не ел...