Goodle Clean Design Architecture

Source: Internet
Author: User

Goodle Clean Design Architecture
* @param <P> The response type24 */25 public abstract class Usecase<q extends Usecase.requestvalues, P exten DS usecase.responsevalue> {mrequestvalues;28 private Q-usecasecallback<p> Musecasecallba ck;30 public void Setrequestvalues (Q requestvalues) {mrequestvalues = requestvalues;33}34/PU Blic Q getrequestvalues () {usecasecallback<p> return mrequestvalues;37}38 Llback () {musecasecallback;41}42, public void Setusecasecallback (usecasecallback<p> use Casecallback) {musecasecallback = usecasecallback;45}46 void run () {executeusecase (mreque stvalues)}50 protected abstract void Executeusecase (Q requestvalues);/**54 * Data passed to      A request.55 */56 public interface Requestvalues {$}58 */**60 * Data received from a request.61 */62 public intErface Responsevalue {}64 N/a public interface usecasecallback<r> {6 void onsuccess (R response); 7 void OnError (); 68}69}

The entity base class UseCase is designed with generics and interfaces, and only two fields Mrequestvalues and Musecasecallback are designed. Wherein, mrequestvalues represents the data request parameter, is encapsulated by the generic type, it is actually a class object, Musecasecallback represents the request result, similarly, it is also the object of a class, but this class is abstract and encapsulated in the form of an interface. At the same time, the abstract method Executeusecase () is defined as the entry for the entity operation in UseCase.

Next, we casually look at a UseCase implementation class, take Activatetask, Activatetask inherited UseCase, its implementation code is as follows:

 1/* 2 * Copyright, the Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the " License "); 5 * You are not a use this file except in compliance with the License. 6 * Obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 *10 * unless re  Quired by applicable-law or agreed-to-writing, SOFTWARE11 * Distributed under the License is distributed on a "as is" basis,12 * without warranties or CONDITIONS of any KIND, either express or implied.13 * See the License for the Specifi C language Governing permissions AND14 * Limitations under the license.15 */16 package com.example.android.architectu RE.BLUEPRINTS.TODOAPP.TASKS.DOMAIN.USECASE;18 Import android.support.annotation.nonnull;20 COM.EXAMPLE.ANDROID.ARCHITECTURE.BLUEPRINTS.TODOAPP.USECASE;22 Import com.example.android.architecture.blueprints.todoapp.data.source.tasksrepository;23 Import Static Com.google.common.base.PreconditionS.checknotnull;25/**27 * Marks a task as active (not completed yet).-*/29 public class Activatetask extends Usecas E<activatetask.requestvalues, activatetask.responsevalue> {in private final tasksrepository mTasksRepository The public activatetask (@NonNull tasksrepository tasksrepository) {mtasksrepository = Checknotnull (Tasks Repository, "Tasksrepository cannot be null!"); }36 Notoginseng @Override38 protected void executeusecase (final requestvalues values) {Activetask String = Values.getactivatetask (); Mtasksrepository.activatetask (Activetask); Getusecasecallback (). OnSuccess (         New Responsevalue ());}43-public static final class Requestvalues implements Usecase.requestvalues {45 46 Private final String mactivatetask;47 requestvalues (@NonNull string activatetask) {$ m Activatetask = Checknotnull (Activatetask, "Activatetask cannot be null!");         50}51 52Public String Getactivatetask () {mactivatetask;54 return}55}56, public static final CLA SS Responsevalue implements Usecase.responsevalue {}58}

As you can see, in Activatetask, the two interfaces requestvalues and Responsevalue of the parent class UseCase are implemented, and the two classes will be the final entity Request object class and return the result object class respectively, at the same time, The abstract method in UseCase Executeusecase () is also implemented. Because generics and interfaces are added to the implemented code, it may seem more complex, but in the end it is nothing more than inheritance and implementation. With this interface-oriented approach, we can make our code look more structured and unified.

Next, we can look at the task execution class Usecasethreadpoolscheduler in this project, and similarly, the Usecasethreadpoolscheduler design uses an interface-oriented approach, It implements the Secasescheduler interface, and the implementations of Usecasescheduler and Usecasethreadpoolscheduler are as follows:

 1/* 2 * Copyright, the Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the " License "); 5 * You are not a use this file except in compliance with the License. 6 * Obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 *10 * unless re  Quired by applicable-law or agreed-to-writing, SOFTWARE11 * Distributed under the License is distributed on a "as is" basis,12 * without warranties or CONDITIONS of any KIND, either express or implied.13 * See the License for the Specifi C language Governing permissions AND14 * Limitations under the license.15 */16 package com.example.android.architectu Re.blueprints.todoapp;18/**20 * Interface for schedulers, see {@link usecasethreadpoolscheduler}.21 */22 public inte Rface Usecasescheduler {$ void execute (Runnable Runnable); <v extends usecase.responsevalue> void n Otifyresponse (Final V response,27 final Usecase.usecaSecallback<v> usecasecallback); <v extends usecase.responsevalue> void OnError (Final U Secase.usecasecallback<v> usecasecallback); 31}
 1/* 2 * Copyright, the Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the " License "); 5 * You are not a use this file except in compliance with the License. 6 * Obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 *10 * unless re  Quired by applicable-law or agreed-to-writing, SOFTWARE11 * Distributed under the License is distributed on a "as is" basis,12 * without warranties or CONDITIONS of any KIND, either express or implied.13 * See the License for the Specifi C language Governing permissions AND14 * Limitations under the license.15 */16 package com.example.android.architectu RE.BLUEPRINTS.TODOAPP;18 Import android.os.handler;20 Import java.util.concurrent.arrayblockingqueue;22 Import JAVA.UTIL.CONCURRENT.EXECUTORS;23 Import java.util.concurrent.threadpoolexecutor;24 Import JAVA.UTIL.CONCURRENT.TIMEUNIT;25/**27 * Executes asynchronous tasks using a {@link Threadpoolexecutor}.28 * <p>29 * See also {@link executors} for a list of factory methods to create Common30 * {@link Java.uti L.concurrent.executorservice}s for different scenarios.31 */32 public class Usecasethreadpoolscheduler implements Usecasescheduler {private final Handler Mhandler = new Handler (); public static final int pool_size = 2 ; Notoginseng public static final int max_pool_size = 4;39-public static final int TIMEOUT = 30;41 Threadpoolex Ecutor mthreadpoolexecutor;43 Usecasethreadpoolscheduler () {mthreadpoolexecutor = new Threadpoole Xecutor (Pool_size, Max_pool_size, timeout,46 timeunit.seconds, new arrayblockingqueue<runnable> (POOL _size)}48 @Override50 public void execute (Runnable Runnable) {Wuyi Mthreadpoolexecutor.execute (r unnable);}53 @Override55 public <v extends usecase.responsevalue> void Notifyresponse (final V resp ONSE,56 Final UsecaSe.             Usecasecallback<v> usecasecallback) {mhandler.post (new Runnable () {@Override59     public void Run () {usecasecallback.onsuccess (response); 61}62}); 63}64 65 @Override66 public <v extends usecase.responsevalue> void OnError (Final usecase.usecasecallback& Lt V> usecasecallback) {mhandler.post (new Runnable () {@Override70 public void run () {Usecasecallback.onerror (); 72}73}); 74}75 76}

As you can see, Usecasethreadpoolscheduler implements the three abstract methods in Usecasescheduler.

Next, let's look at the Usecasehandler class, which, in Usecasehandler, instantiates the Usecasescheduler object with Usecasethreadpoolscheduler in the form of a subclass instantiation of the parent class. The code for Usecasehandler is as follows:

/* * Copyright, the Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * You are not a use this file except in compliance with the License. * Obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * unless required by appli Cable law or agreed into writing, software * Distributed under the License is distributed on a "as is" BASIS, * without Warranties or CONDITIONS of any KIND, either express OR implied. * See the License for the specific language governing permissions and * limitations under the License. */package Com.example.android.architecture.blueprints.todoapp;import com.example.android.architecture.blueprints.todoapp.util.espressoidlingresource;/** * Runs {@link UseCase}s using a { @link Usecasescheduler}.    */public class Usecasehandler {private static Usecasehandler INSTANCE;    Private final Usecasescheduler Musecasescheduler; Public Usecasehandler (Usecasescheduler Usecasescheduler) {        Musecasescheduler = Usecasescheduler; } public <t extends Usecase.requestvalues, R extends usecase.responsevalue> void execute (Final Usecas        E<t, r> usecase, T values, usecase.usecasecallback<r> callback) {usecase.setrequestvalues (values);        Usecase.setusecasecallback (New Uicallbackwrapper (callback, this));  The network request might is handled in a different thread so make sure//Espresso knows//the app        is busy until the response is handled. Espressoidlingresource.increment (); APP is busy until further notice Musecasescheduler.execute (new Runnable () {@Override Publ                IC void Run () {usecase.run (); This callback is called twice, once for the cache and once in loading//The data from the server A    PI, so we check before decrementing, otherwise//it throws "Counter have been corrupted!" exception.            if (! Espressoidlingresource.getidlingresource (). Isidlenow ()) {espressoidlingresource.decrement ();//Set AP                P as idle.    }            }        }); } public <v extends usecase.responsevalue> void Notifyresponse (Final V response, final usecase.usecase    Callback<v> usecasecallback) {musecasescheduler.notifyresponse (response, Usecasecallback); } private <v extends usecase.responsevalue> void notifyerror (Final usecase.usecasecallback<v> u    Secasecallback) {musecasescheduler.onerror (usecasecallback); } private static Final class Uicallbackwrapper<v extends usecase.responsevalue> implements Usecase.use        casecallback<v> {private final usecase.usecasecallback<v> mcallback;        Private final Usecasehandler Musecasehandler; Public Uicallbackwrapper (Usecase.usecasecallback<v> callback, Usecasehandler Usecasehandler) {Mcallback = callback;        Musecasehandler = Usecasehandler; } @Override public void onsuccess (V response) {Musecasehandler.notifyresponse (response, Mcallbac        k);        } @Override public void OnError () {musecasehandler.notifyerror (mcallback); }} public static Usecasehandler getinstance () {if (INSTANCE = = null) {INSTANCE = new Usecasehan        Dler (New Usecasethreadpoolscheduler ());    } return INSTANCE; }}

From the code above, we can see that the declared variable Musecasescheduler is an object of Usecasescheduler, but when building Usecasehandler objects, The passed-in parameter is a Usecasethreadpoolscheduler object, that is, the Usecasescheduler object is instantiated with Usecasethreadpoolscheduler. All operations on the Musecasescheduler are then translated into operations on the Usecasethreadpoolscheduler object.

Then, as we look closely at the implementation code of Usecasehandler, we will find that the entry that actually operates on the entity is the Execute () Method! Because this method calls the UseCase run (), and UseCase's run () eventually calls UseCase's Executeusecase (). With this analysis, we should know that the entity we are actually manipulating should be the UseCase implementation class, not the UseCase class itself, so what is the middle of the way to transfer the operations of UseCase to the UseCase implementation class? We'll find out that Usecasehandler's execute () passed in the UseCase object as a parameter, OK, so let's see where execute () is called.

After tracing, we see that this method is called in the Taskspresenter class, and the code at the call is as follows:

1 @Override 2 public     void Activatetask (@NonNull Task activetask) {3         checknotnull (activetask, "Activetask cannot Be null! "); 4         Musecasehandler.execute (Mactivatetask, New Activatetask.requestvalues (Activetask.getid ()), 5                 New Usecase.usecasecallback<activatetask.responsevalue> () {6                     @Override 7 public                     void Onsuccess ( Activatetask.responsevalue response) {8                         mtasksview.showtaskmarkedactive (); 9                         Loadtasks (False, false); 10                     }11                     @Override13 public                     void OnError () {                         mtasksview.showloadingtaskserror ();                     }16                 }); +     }

As you can see, the parameters we pass in are actually objects of the UseCase implementation class Activatetask, and here we get it! It is also the way subclasses instantiate the parent class.

I'm just going to tell you a little bit about the code of some of the modules in the project, just for example, more things need to be understood by the object-oriented mind. I said that the purpose of this is to tell you that the full transport of object-oriented ideas can be designed to create a lot of seemingly complex architecture and projects, but no matter how complex code is certainly a trace, we just grasp the essence of these design ideas, read a few times code, will be enlightened!

Goodle Clean Design Architecture

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.