Analysis of Android source code design patterns and practices (16)

Source: Internet
Author: User
Tags class manager

Analysis of Android source code design patterns and practices (16)
Chapter 2 visitor Mode

Visitor mode is a behavior mode. It is the most complex of the 23 design modes. Although the frequency of use is not high, it does not mean that it can be ignored, it brings unexpected flexibility. Visitor mode, as the name implies, with this mode, you can add additional "visitors" without modifying the existing program structure to improve the existing code functions.

1. Definition

Encapsulate operations that act on each element in a data structure. It can define new operations that act on these elements without changing the data structure.

2. Use Cases

(1) The object structure is relatively stable, but it is often necessary to define new operations on this object structure.

(2) You need to perform many different and unrelated operations on the objects in an object structure. Instead, you need to avoid "polluting" the classes of these objects, you do not want to modify these classes when adding new operations.

3. UML class diagram

(1) Visitor:Interface or abstract classIt defines the access behavior to each Element. Its parameter is the Element that can be accessed. The number of methods is theoretically the same as the number of elements. Therefore, the visitor mode requires the elementClass families must be stableIf you add or remove element classes frequently, the Visitor interface will be modified frequently. If so, the Visitor mode is not suitable.

(2) ConcreteVisitor1 and ConcreteVisitor2:Specific categoryIt needs to show the specific behavior generated when accessing each element class.

(3) Element:Element interface or abstract classIt defines an Accept method, which means that each element can be accessed by a visitor.

(4) ConcreteElementA and ConcreteElementB:Specific element classesIt provides the specific implementation of the access method, and the specific implementation is usually the method provided by the visitor to access this element class.

(5) ObjectStructure: the object structure mentioned in the definition. The object structure is an abstract expression. It manages the element set internally and can iterate these elements for access by visitors.

4. Simple implementation

Scenario: at the end of the year, the company will evaluate the performance of its employees. However, management personnel in different fields have different evaluation standards for employees. Now the employees have the siege lions and managers, and the reviewers are the CEOs and ctos. We assume that the CTO only focuses on the Code volume of the siege lions and the number of new products of the managers, the CEO is concerned with the KPI of siege lions, the KPI of managers, and the number of new products.

Employee base class:

/*** Employee base class (Element) */public abstract class Staff {// employee name public String name; // employee KPI public int kpi; public Staff (String name) {super (); this. name = name; this. kpi = new Random (). nextInt (10);} // accept the access from the Visitor public abstract void accept (Visitor visitor );}

Siege lions:

/*** Siege lion */public class Engineer extends Staff {private int codeLines; // number of codes public Engineer (String name) {super (name ); codeLines = new Random (). nextInt (10*10000);} @ Override public void accept (Visitor visitor) {visitor. visit (this);} // number of codes written by the attacker in the year public int getCodeLines () {return codeLines ;}}

Manager:

/*** Manager */public class Manager extends Staff {private int products; // number of products public Manager (String name) {super (name); products = new Random (). nextInt (10) ;}@ Override public void accept (Visitor visitor) {visitor. visit (this);} // number of products created in one year public int getProducts () {return products ;}}

Visitor class:

Public interface Visitor {/*** access to the siege Lions type */public void visit (Engineer engineer);/*** Access Manager type */public void visit (manager Manager );}

CEO Visitor:

Public class CEOVisitor implements Visitor {@ Override public void visit (Engineer engineer) {System. out. println ("siege LION:" + engineer. name + ", KPI:" + engineer. kpi) ;}@ Override public void visit (Manager manager) {System. out. println ("manager:" + manager. name + ", KPI:" + manager. kpi + ", number of new products:" + manager. getProducts ());}}

CTO category:

Public class CTOVisitor implements Visitor {@ Override public void visit (Engineer engineer) {System. out. println ("siege LION:" + engineer. name + ", code quantity:" + engineer. getCodeLines ();} @ Override public void visit (Manager manager) {System. out. println ("manager:" + manager. name + ", product quantity:" + manager. getProducts ());}}

Employee report type:

// ObjectStructure public class BusinessReport {List
  
   
MStaffs = new parameter list
   
    
(); Public BusinessReport () {mStaffs. add (new Manager ("Manager Wang"); mStaffs. add (new Engineer ("siege lions-A"); mStaffs. add (new Engineer ("siege lions-B"); mStaffs. add (new Manager ("Manager Li"); mStaffs. add (new Engineer ("siege lion-C");}/*** display report for visitors * @ param visitor such as CEO, CTO */public void showReport (Visitor visitor) {for (Staff staff: mStaffs) {staff. accept (visitor );}}}
   
  

Client Access:

Public class Client {public static void main (String [] args) {// construct the report BusinessReport report = new BusinessReport (); System. out. println ("==== show the report to the CEO ===="); // set the report to the CEO of the visitor. showReport (new CEOVisitor (); System. out. println ("==== show the report to the CTO ===="); // set the CTO report for the visitor. showReport (new CTOVisitor ());}}

Result:

=======Show the Report to the CEO ====== MANAGER: Manager Wang, KPI: 2, number of new products: 5 siege lions: siege lions-A, KPI: 5 siege lions: siege lions-B, KPI: 7 MANAGER: Li manager, KPI: 9, new product quantity: 8 siege lions: siege lions-C, KPI: 1 =======show the report to CTO ====== MANAGER: Manager Wang, product quantity: 5 siege lions: siege lions-A, number of codes: 26238 siege lions: siege lions-B, code quantity: 8282 managers: Manager Li, product quantity: 8 siege lions: siege lions-C, code quantity: 47927

From the code above, we can see that if you want to add a Visitor, you will create a new class that implements the Visitor interface, and then implement two visit methods to perform different operations on different elements, this separates Data Objects from data operations. If you do not use the visitor mode and want to perform different operations on different elements, you must use if-else and type conversion, which makes it difficult to upgrade and maintain the code.

5. Visitor mode in Android

The famous open-source libraries ButterKnife, Dagger, and fit in Android are all implemented based on APT (Annotation Processing Tools. The core of the compilation annotation is APT. When we use APT to process annotations, the obtained elements are eventually converted into corresponding Element elements to obtain their corresponding information. The source code of the element base class is as follows: (Path: javax. lang. model. Element. element)

Public interface Element extends javax. lang. model. annotatedConstruct {/*** Returns the {@ code kind} of this element. ** @ return the kind of this element */ElementKind getKind (); // get the element type // Code omitted/*** Applies a visitor to this element. ** @ param
  
   
The return type of the visitor's methods * @ param
  

The type of the additional parameter to the visitor's methods * @ param v the visitor operating on this element * @ param p additional parameter to the visitor * @ return a visitor-specified result */ R accept (ElementVisitor V, P p); // accept the visitor's access}

ElementVisitor is the visitor type. The ElementVisitor source code is as follows:

public interface ElementVisitor
  
    {    /**     * Visits an element.     * @param e  the element to visit     * @param p  a visitor-specified parameter     * @return a visitor-specified result     */    R visit(Element e, P p);    /**     * A convenience method equivalent to {@code v.visit(e, null)}.     * @param e  the element to visit     * @return a visitor-specified result     */    R visit(Element e);    /**     * Visits a package element.     * @param e  the element to visit     * @param p  a visitor-specified parameter     * @return a visitor-specified result     */    R visitPackage(PackageElement e, P p);    /**     * Visits a type element.     * @param e  the element to visit     * @param p  a visitor-specified parameter     * @return a visitor-specified result     */    R visitType(TypeElement e, P p);    /**     * Visits a variable element.     * @param e  the element to visit     * @param p  a visitor-specified parameter     * @return a visitor-specified result     */    R visitVariable(VariableElement e, P p);    /**     * Visits an executable element.     * @param e  the element to visit     * @param p  a visitor-specified parameter     * @return a visitor-specified result     */    R visitExecutable(ExecutableElement e, P p);    /**     * Visits a type parameter element.     * @param e  the element to visit     * @param p  a visitor-specified parameter     * @return a visitor-specified result     */    R visitTypeParameter(TypeParameterElement e, P p);    /**     * Visits an unknown kind of element.     * This can occur if the language evolves and new kinds     * of elements are added to the {@code Element} hierarchy.     *     * @param e  the element to visit     * @param p  a visitor-specified parameter     * @return a visitor-specified result     * @throws UnknownElementException     *  a visitor implementation may optionally throw this exception     */    R visitUnknown(Element e, P p);}
  

Multiple visit interfaces are defined in ElementVisitor. Each interface processes one element type, which is a typical visitor mode.

6. Summary 1. Advantages

(1) separation of duties of each role, in line with the single responsibility principle.

(2) excellent scalability.

(3) decoupling the data structure from the operation acting on the structure, so that the operation set can be changed independently.

(4) flexibility.

2. Disadvantages

(1) The specific elements reveal details to visitors, in violation of the dimit principle.

(2) Changes to specific elements lead to high modification costs.

(3) The dependency inversion principle is violated. To achieve "differentiated treatment", the dependency on specific classes is not abstract.

Related Article

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.