Android and Design mode: decoupling activity with a single responsibility principle

Source: Internet
Author: User
<span id="Label3"></p>I. What is the principle of single responsibility<p><p>The single principle of responsibility (srp:single responsibility principle), also known as the single function principle, is defined as: a class, there should be only one cause of change. The concept of light can make people very headache, let me start with a few examples:</p></p>second, the single responsibility principle can solve what problem<p><p>Looking back on our Android development experience, Many people will find that the code in the Activity class will always become a lot more, which makes it very painful for the people who read our Code. One of the reasons for this is that the activity requires a lot of interaction with the user, and the User's actions change the interface elements/corresponding information currently displayed by the activity, so we always put the Model, View, click event and so on ... Operations are all put into the activiy, but there is a very serious problem, no brain to add code for activity, it is bound to make the activity become bloated, structural confusion, vague responsibilities, especially the engineer who was responsible for the project has left, the new engineer needs to reconstruct the Activity, it will be Painful.</p></p><p><p>So how do we decouple the Activity? I'm going to go through a little Demo. decoupling the Activity with the idea of a single duty principle, as Follows:</p></p><p><p></p></p><p><p></p></p><pre class="prettyprint"><code class="language-java hljs "> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">Data</span> {</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>String Btn1str =<span class="hljs-string"><span class="hljs-string">"btn1 Clicked 1"</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>String Btn2str =<span class="hljs-string"><span class="hljs-string">"btn2 Clicked 1"</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>String Btn3str =<span class="hljs-string"><span class="hljs-string">"btn3 Clicked 1"</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>String Btn4str =<span class="hljs-string"><span class="hljs-string">"btn4 Clicked 1"</span></span>;<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span>String<span class="hljs-title"><span class="hljs-title">GetData</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Index) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(index = =<span class="hljs-number"><span class="hljs-number">1</span></span>)<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>btn1str;<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(index = =<span class="hljs-number"><span class="hljs-number">2</span></span>)<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>btn2str;<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(index = =<span class="hljs-number"><span class="hljs-number">3</span></span>)<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>btn3str;<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>btn4str; }<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">SetData</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Index,string Str) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(index = =<span class="hljs-number"><span class="hljs-number">1</span></span>) Btn1str = str;<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(index = =<span class="hljs-number"><span class="hljs-number">2</span></span>) Btn2str = str;<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(index = =<span class="hljs-number"><span class="hljs-number">3</span></span>) Btn3str = str;<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span>Btn4str = str; } }</code></pre><pre class="prettyprint"><code class="language-java hljs "> <span class="hljs-keyword"><span class="hljs-keyword">Import</span></span>android.app.Activity;<span class="hljs-keyword"><span class="hljs-keyword">Import</span></span>android.os.Bundle;<span class="hljs-keyword"><span class="hljs-keyword">Import</span></span>android.view.View;<span class="hljs-keyword"><span class="hljs-keyword">Import</span></span>android.view.View.OnClickListener;<span class="hljs-keyword"><span class="hljs-keyword">Import</span></span>android.widget.Button;<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">mainactivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Activity</span> <span class="hljs-keyword"></span> implements <span class="hljs-title"> Onclicklistener</span>{</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Button btn1;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Button btn2;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Button btn3;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Button btn4;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Data data =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Data ();<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword">protected</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">onCreate</span></span>(Bundle Savedinstancestate) {<span class="hljs-keyword"><span class="hljs-keyword">Super</span></span>. onCreate (savedinstancestate); Setcontentview (r.layout.activity_main); BTN1 = (Button) Findviewbyid (r.id.button1); BTN2 = (Button) Findviewbyid (r.id.button2); Btn3 = (Button) Findviewbyid (r.id.button3); Btn4 = (Button) Findviewbyid (r.id.button4); Btn1.setonclicklistener (<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>); Btn2.setonclicklistener (<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>); Btn3.setonclicklistener (<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>); Btn4.setonclicklistener (<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>); }<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">UpdateData</span></span>(){<span class="hljs-comment"><span class="hljs-comment">//various Network Request operations Update data</span></span>}<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">OnClick</span></span>(View V) {<span class="hljs-keyword"><span class="hljs-keyword">Switch</span></span>(v.getid ()) {<span class="hljs-keyword"><span class="hljs-keyword"></span> case</span>R.id.button1:btn1.settext (data.getdata (<span class="hljs-number"><span class="hljs-number">1</span></span>));<span class="hljs-keyword"><span class="hljs-keyword"></span> break</span>;<span class="hljs-keyword"><span class="hljs-keyword"></span> case</span>R.id.button2:btn2.settext (data.getdata (<span class="hljs-number"><span class="hljs-number">2</span></span>));<span class="hljs-keyword"><span class="hljs-keyword"></span> break</span>;<span class="hljs-keyword"><span class="hljs-keyword"></span> case</span>R.id.button3:btn3.settext (data.getdata (<span class="hljs-number"><span class="hljs-number">3</span></span>));<span class="hljs-keyword"><span class="hljs-keyword"></span> break</span>;<span class="hljs-keyword"><span class="hljs-keyword"></span> case</span>R.id.button4:btn4.settext (data.getdata (<span class="hljs-number"><span class="hljs-number">4</span></span>));<span class="hljs-keyword"><span class="hljs-keyword"></span> break</span>; } } }</code></pre><p><p>In the Demo we can see that all the relevant operations are carried out in the Activity, you know, this is just a very simple page, you can say that there is no business logic at All. To a complex business logic page, which is also used to play? Let's move on to a different idea, using MVP mode decoupling:</p></p><pre class="prettyprint"><code class="language-java hljs "> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">Presenter</span> {</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Data data;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>IView IView;<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-title"><span class="hljs-title">Presenter</span></span>(IView IView) {<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>. IView = iView; data =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Data (); }<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span>Data<span class="hljs-title"><span class="hljs-title">GetData</span></span>(){<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>Data }<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">SetData</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Index,string Str) {<span class="hljs-comment"><span class="hljs-comment">//various Network requests to update data</span></span>Data.setdata (index, str); Updateview (); }<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Updateview</span></span>() {iview.updateview (data); } }</code></pre><pre class="prettyprint"><pre class="prettyprint"><code class="language-java hljs "> <span class="hljs-keyword">public</span><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">IView</span> {</span> <span class="hljs-keyword">public</span><span class="hljs-keyword">void</span><span class="hljs-title">updateView</span>(Data data); }</code></pre></pre><pre class="prettyprint"><code class="language-java hljs "> <span class="hljs-keyword"><span class="hljs-keyword">Import</span></span>android.app.Activity;<span class="hljs-keyword"><span class="hljs-keyword">Import</span></span>android.os.Bundle;<span class="hljs-keyword"><span class="hljs-keyword">Import</span></span>android.view.View;<span class="hljs-keyword"><span class="hljs-keyword">Import</span></span>android.view.View.OnClickListener;<span class="hljs-keyword"><span class="hljs-keyword">Import</span></span>android.widget.Button;<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">mainactivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Activity</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IView</span>, <span class="hljs-title"> Onclicklistener</span>{</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Button btn1;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Button btn2;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Button btn3;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Button btn4;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Presenter Presenter;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Data data =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Data ();<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword">protected</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">onCreate</span></span>(Bundle Savedinstancestate) {<span class="hljs-keyword"><span class="hljs-keyword">Super</span></span>. onCreate (savedinstancestate); Setcontentview (r.layout.activity_main); BTN1 = (Button) Findviewbyid (r.id.button1); BTN2 = (Button) Findviewbyid (r.id.button2); Btn3 = (Button) Findviewbyid (r.id.button3); Btn4 = (Button) Findviewbyid (r.id.button4); Btn1.setonclicklistener (<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>); Btn2.setonclicklistener (<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>); Btn3.setonclicklistener (<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>); Btn4.setonclicklistener (<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>); Presenter =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Presenter (<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>); }<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Updateview</span></span>(data Data) {<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>. data = data; }<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">OnClick</span></span>(View V) {<span class="hljs-keyword"><span class="hljs-keyword">Switch</span></span>(v.getid ()) {<span class="hljs-keyword"><span class="hljs-keyword"></span> case</span>R.id.button1:btn1.settext (data.getdata (<span class="hljs-number"><span class="hljs-number">1</span></span>));<span class="hljs-keyword"><span class="hljs-keyword"></span> break</span>;<span class="hljs-keyword"><span class="hljs-keyword"></span> case</span>R.id.button2:btn2.settext (data.getdata (<span class="hljs-number"><span class="hljs-number">2</span></span>));<span class="hljs-keyword"><span class="hljs-keyword"></span> break</span>;<span class="hljs-keyword"><span class="hljs-keyword"></span> case</span>R.id.button3:btn3.settext (data.getdata (<span class="hljs-number"><span class="hljs-number">3</span></span>));<span class="hljs-keyword"><span class="hljs-keyword"></span> break</span>;<span class="hljs-keyword"><span class="hljs-keyword"></span> case</span>R.id.button4:btn4.settext (data.getdata (<span class="hljs-number"><span class="hljs-number">4</span></span>));<span class="hljs-keyword"><span class="hljs-keyword"></span> break</span>; } } }</code></pre><p><p>What happens to the Activity class after such refactoring? Let's recall the definition of Activity in the Android SDK:</p></p> <blockquote> <blockquote> <p>An activity was a single, focused thing that the user can do. Almost all activities interact with the user, and the Activity class takes care of creating a window for you in which C A place your UI with {@link #setContentView}. While activities is often presented to the user as Full-screen windows, They can also is used in other ways:as floating Windows (via a theme with {@link Android. r.attr#windowisfloating} Set) or embedded inside of another activity (using {@link activitygroup}).</p> </blockquote> </blockquote><p><p>Simple translation: activity symbolizes one thing that the user can accomplish, and most of the activity is used to interact with the user in which to place our UI.</p></p><p><p>In other words, Google officially believes that the role of Activity is to render the UI and interact with the User.</p></p><p><p>The previous code clearly violates the principle of single responsibility, since the Activity requires not only the request and update of the data, but the modification of the View based on the User's interactive/updated Data. So what does the new code do to change what happened to the Activity? first, the request/update of the data is processed by Presenter, does not need to go through the Activity to request/update; second, the View-related logic (e.g., Modification) is provided by the IView interface, and the Activity needs only to accomplish the specific Implementation.</p></p>Iii. What are the benefits of following a single responsibility principle?<p><p>So what is the benefit of such refactoring? I believe that after reading the example, you will be a little bit unclear, the way of the unknown, especially recall the past write some bad structure of the code when the touch will be deeper. In fact, I personally think that the idea in the design pattern and the idea of the efficient organization and completion of the work in the life are consistent, because the so-called design pattern, itself is the predecessor to write the code the experience summary, its goal is: enhances the efficiency, facilitates the maintenance, makes the code easy to read, easy to expand and so on ... Looking back on life, if we want a team/organization/company/enterprise to operate efficiently, then this group will have to <strong>re-define the division of responsibilities within the departmental communication specifications---for example the UI department is divided into: visual design, Interactive design and so On. ) and the Department members clear division of Labor</strong> , as far as possible to make the whole group structure as modular, low-coupling, high cohesion, The role of clear structure.</p></p><p><p>and the single responsibility principle embodies the same idea, a class, should only be affected by its most fundamental abstract logic, the specific changes within the class should come from the abstract logic, we say a single duty, I think its meaning is not <strong>a class to do one thing</strong> , but that <strong>a class is an abstract group, An abstract group has its own attributes and responsibilities, and its responsibilities may require it to do many things, but its responsibilities are always unique</strong> .</p></p><p><p>After such refactoring we can strip out the logic within the class that does not belong to it, and let the class follow its abstract logic without adding code to other duties that do not belong to it.</p></p> <p><p>Android and Design mode: decoupling activity with a single responsibility principle</p></p></span>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.