{"id":1127,"date":"2021-01-03T10:52:19","date_gmt":"2021-01-03T09:52:19","guid":{"rendered":"http:\/\/mateuszglowinski.pl\/?p=1127"},"modified":"2021-01-03T14:13:03","modified_gmt":"2021-01-03T13:13:03","slug":"state-programming-pattern","status":"publish","type":"post","link":"https:\/\/mateuszglowinski.pl\/index.php\/2021\/01\/03\/state-programming-pattern\/","title":{"rendered":"State Programming Pattern"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"1127\" class=\"elementor elementor-1127\" data-elementor-settings=\"[]\">\n\t\t\t\t\t\t<div class=\"elementor-inner\">\n\t\t\t\t\t\t\t<div class=\"elementor-section-wrap\">\n\t\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-dd5aaea elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"dd5aaea\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t\t\t<div class=\"elementor-row\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-e1c78e1\" data-id=\"e1c78e1\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-column-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t<div class=\"elementor-widget-wrap\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-ae2d8b9 elementor-widget elementor-widget-text-editor\" data-id=\"ae2d8b9\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"elementor-text-editor elementor-clearfix\"><h2>Introduction<\/h2>\n<div>State programming pattern allow the object for changing its behavior without changing its class.&nbsp; Also, by implementing it, the code should remain cleaner without many if\/else statements. The whole idea of this pattern is based on <a href=\"https:\/\/en.wikipedia.org\/wiki\/Finite-state_machine\">Finite State Machine<\/a><\/div>\n<h2>Definition<\/h2>\n<p>State is a behavioral design pattern that lets an object alter its behavior when its internal state changes. It appears as if the object changed its&nbsp;class.<\/p>\n<p><img loading=\"lazy\" class=\"aligncenter\" src=\"http:\/\/mateuszglowinski.pl\/wp-content\/uploads\/2021\/01\/StateProgrammingPatternUML.png\" alt=\"\" width=\"610\" height=\"410\"><\/p>\n<div>\n<h2>Problem solved by &#8222;State&#8221;<\/h2>\n<p>A monolithic object&#8217;s behavior is a function of its state, and it must change its behavior at run-time depending on that state. Or, an application is characterized by large and numerous case statements that vector flow of control based on the state of the application.<\/p>\n<p>In this example we will consider a fan control.<\/p>\n<pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">class Fan {\n    private int currentState;\n\n    public Fan() {\n        currentState = 0;\n    }\n\n    public void pull() {\n        if (currentState == 0) {\n            currentState = 1;\n            System.out.println(\"low speed\");\n        } else if (currentState == 1) {\n            currentState = 2;\n            System.out.println(\"medium speed\");\n        } else if (currentState == 2) {\n            currentState = 3;\n            System.out.println(\"high speed\");\n        } else {\n            currentState = 0;\n            System.out.println(\"turning off\");\n        }\n    }\n}\n<\/pre>\n<\/div>\n<p>Let&#8217;s test our fan.<\/p>\n<div>\n<pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public class CoolingSystem {\n    public static void main(String[] args) {\n        Fan fan = new Fan();\n        fan.pull(); \/\/ set low speed\n        fan.pull(); \/\/ set medium speed\n        fan.pull(); \/\/ set high speed\n        fan.pull(); \/\/ turn off\n        fan.pull(); \/\/ set low speed\n    }\n}\n<\/pre>\n<\/div>\n<h2>Solution<\/h2>\n<p>Let&#8217;s start implementing State Pattern with creating interface for state. It should contain a method, which will set a fan to particular speed in <span lang=\"en\"><span data-language-for-alternatives=\"en\" data-language-to-translate-into=\"pl\" data-phrase-index=\"0\">the classes which will implement this interface. This metod should take Fan object as argument, due to that we need easy way for chaning state and Fan class will have a function for that.<br><\/span><\/span><\/p>\n<pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">interface State {\n    void pull(Fan wrapper);\n}\n<\/pre>\n<p>In next step let&#8217;s prepare state classes like on below diagram.<\/p>\n<h2><img loading=\"lazy\" class=\"aligncenter\" src=\"http:\/\/mateuszglowinski.pl\/wp-content\/uploads\/2021\/01\/FanStateFlowDiagram.png\" alt=\"\" width=\"245\" height=\"648\"><\/h2>\n<p>Notice that every state do have information about next state.<\/p>\n<pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">class Off implements State {\n\n    public Off(){\n        System.out.println(\"Turning off\");\n    }\n\n    public void pull(Fan wrapper) {\n        System.out.println(\"Preparation to move from Off State to Low State\");\n        wrapper.setState(new Low());\n    }\n}\n<\/pre>\n<pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">class Low implements State {\n\n    public Low(){\n        System.out.println(\"Low speed\");\n    }\n\n    public void pull(Fan wrapper) {\n        System.out.println(\"Preparation to move from Low State to Medium State\");\n        wrapper.setState(new Medium());\n    }\n}\n<\/pre>\n<pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">class Medium implements State {\n\n    public Medium(){\n        System.out.println(\"Medium speed\");\n    }\n\n    public void pull(Fan wrapper) {\n        System.out.println(\"Preparation to move from Medium State to High State\");\n        wrapper.setState(new High());\n    }\n}\n<\/pre>\n<pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">class High implements State {\n\n    public High(){\n        System.out.println(\"High speed\");\n    }\n\n    public void pull(Fan wrapper) {\n        System.out.println(\"Preparation to move from High State to Off State\");\n        wrapper.setState(new Off());\n    }\n}\n<\/pre>\n<p>Last step is adjusting Fan class. It is important to implement function for changing state here.<\/p>\n<pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">class Fan {\n    private State currentState;\n\n    public Fan() {\n        currentState = new Off();\n    }\n\n    public void setState(State s) {\n        currentState = s;\n    }\n\n    public void pull() {\n        currentState.pull(this);\n    }\n}\n<\/pre>\n<h2>Pros<\/h2>\n<div>\n<ul>\n<li><em>Single Responsibility Principle<\/em>. Organize the code related to particular states into separate classes.<\/li>\n<li><em>Open\/Closed Principle<\/em>. Introduce new states without changing existing state classes or the context.<\/li>\n<li>Simplify the code of the context by eliminating bulky state machine conditionals.<\/li>\n<\/ul>\n<div>\n<h2>Cons<\/h2>\n<div>\n<ul>\n<li>Applying the pattern can be overkill if a state machine has only a few states or rarely changes.<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div><\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Introduction State programming pattern allow the object for changing its behavior without changing its class.&nbsp; Also, by implementing it, the code should remain cleaner without&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[27],"tags":[23],"_links":{"self":[{"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/posts\/1127"}],"collection":[{"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/comments?post=1127"}],"version-history":[{"count":65,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/posts\/1127\/revisions"}],"predecessor-version":[{"id":1463,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/posts\/1127\/revisions\/1463"}],"wp:attachment":[{"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/media?parent=1127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/categories?post=1127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/tags?post=1127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}