Now many companies will consider the componentization scheme after their business expands to a certain extent or their business model runs, and the mainstream approach of componentization scheme is the following three kinds at present. Here we will talk about our own thinking about the componentization scheme.

  • URL Scheme
  • Protocol Class
  • Target Action

URL Schemeplan

Implementation method:

Services provided by the component are registered at startup (register URL and associated service Block), and then invoked directly from URL (openURL) when used.

  • Use urls to handle local jump logic
  • Registration component, maintains the URL registration service in memory

Advantages:

  • The inconsistency between clients on different platforms is unified
  • It is convenient to handle web page jump

Disadvantages:

  • Url parameters are limited (e.g. non-string types, UIImage, XXModel, NSData, etc.)
  • Business is decentralized and coupled
  • A large number of components may affect memory

Protocol Classplan

Implementation method:

Protocol defines the service interface, and components provide services by implementing the interface. The final implementation is to map Protocol and Class together, and store a mapping table in memory. When using Protocol, the corresponding service of Class is obtained through Protocol.

  • Add a Protocol Wrapper layer
  • The middleware returns the Class corresponding to Protocol
  • Solve the hard coding problem

Advantages:

  • Protocol interface specification, following the dependency inversion principle

Disadvantages:

  • Lack of unified scheduling layer, scattered component method invocation, difficult to centralized management (large team size, architecture control is more important)
  • The architecture is not flexible enough

Target Actionplan

Implementation method:

Target Action This scheme is based on ObjC’s Runtime and category features to dynamically fetch modules, such as NSClassFromString fetching classes and creating instances. Call the method dynamically via performSelector + NSInvocation.

First, each module needs to configure Target and Category. Target is one or more targets corresponding to each component, and Category is the classification of mediators at the middle layer. The purpose of using classification is to separate the business codes of Mediators. Thus reducing the dependency and coupling of mediators. How does mediators find and invoke components? This takes advantage of the Runtime reflection mechanism to find the Target in the Category and call the Target Action.

CTMediator is the Target Action scheme adopted by cocoaTouch. It skillfully uses the reflection mechanism, method signature and command mode provided by cocoaTouch, which simply and perfectly solves the decoupling problem between components.

  • Detach business layer logic
  • Provides logic to be invoked from the middle tier
  • Runtime reflection is used on mid-tier implementations

Advantages:

  • Decoupled, with only a component dependency middle layer (one-way dependency)
  • Compile checking takes advantage of interfaces that categories can explicitly declare
  • Unified processing of all components call entry, easy management

Disadvantages:

  • Each component’s Category corresponds to a Target, and the Action in the Category corresponds to the Action in the Target. (There is a lot of code in this class)
  • There are problems with hard coding various definitions of string

Componentized thinking

Having written about the differences between componentized solutions, let me give you my own view of componentized architecture.

First, the biggest purpose of componentization is to decouple and expand easily. The first thing we need to think about is how to decouple modules directly and how to subdivide them. The principle of module division should be based on what, this should be combined with the business to split.

We then built an architecture that was easy to maintain and extend based on the following five principles of SOLID:

  • Single function principle
  • The open closed principle
  • Richter’s substitution principle
  • Interface Isolation Principle
  • Dependency inversion principle

Finally, the separated modules are packaged into libraries through Cocoapod for management.

Wait, this is the end of it? Of course, there is no decoupling of calls between components, so our componentized architecture comes into play. We need to clarify the dependencies between components and call logic, and divide the hierarchy. The layers between components can be divided into:

  • Bottom layer (Base component)
  • Middle tier (common business components)
  • The business layer

At present, componentization architecture is mainly divided into protocol-class (Mushroom Street scheme) and target-Action (CTMediator). In my opinion, the former may be suitable for teams focusing more on HTML. The biggest problem with protocol is the lack of unified management. The advantage of the latter is that the architecture is easy to control and expand, so it is recommended to use the latter.

Of course, the ultimate choice of architecture is to decouple the business and make the project easier to maintain and expand new business. Many people pursue perfectionism, the ideal of decoupling. In my opinion, componentization focuses on decoupling of the business layer, and the foundation of componentization is to have a good infrastructure.