There are three common componentization schemes in the market.
- MGJRouter
- BeeHive
- CTMediator
MGJRouter
MGJRouter
Url-block, according to the URL to find the corresponding code block to execute.
Simple understanding of registration and invocation
// register url + (void)registerURLPattern:(NSString *)URLPattern toHandler:(MGJRouterHandler)handler; The singleton of the MGJRouter has a routes attribute of type NSMutableDictionaryCopy the code
Ex. :
[MGJRouter registerURLPattern:@" MGJ ://foo/bar" toHandler:^(NSDictionary *routerParameters) {[self appendLog:@" matched url, [self appendLog:[NSString stringWithFormat:@"routerParameters:%@", routerParameters]];}]; [self appendLog:[NSString stringWithFormat:@"routerParameters:%@", routerParameters]];}];Copy the code
Add the following key-value pair to the routes in the singleton of the MGJRouter:
routes = {
mgj = {
foo = {
bar = {
"_" = "<__NSMallocBlock__: 0x600000d8c6f0>";
};
};
};
}
Copy the code
When we call the open: URL.
+ (void)openURL:(NSString *)URL;
Copy the code
This is equivalent to assigning the _ corresponding block in routes to the instance of the MGJRouterHandler to execute the corresponding block.
optimal
- By binding the route to the code block, the invocation of its own module is relatively clear.
- The pass-through of parameters is resolved according to the routing mode and can be extended very well.
bad
- Hard coded problems that each component’s parameter call needs to find. Mogujie has its own set of web pages for unified management, controlling urls and all parameters.
- All of the
url
andblock
Registered in memory, there will be memory problems after more components. - There is no way to distinguish between local and remote calls, and the limitations of parameters may result in limited remote functionality
- Components depend on middleware, and there is more decentralized registration coupling.
BeeHive
BeeHive
In protocol-class mode, find the corresponding Class according to the Protocol and call it.
Class
implementationProtocol
The external interface definedProtocol
Exposed for external use.
emphasis
BHModuleProtocol
: Module manages Module registration and releaseBHServiceProtocol
: is responsible for the component’s open interface
The core is that the singleton BHServiceManager is responsible for mutable dictionary allServicesDict properties that store
NSString: NSString: class nameCopy the code
When fetched, the class is retrieved according to the protocol, and the runtimeAPI creates the class, which can call functions and properties within the protocol.
optimal
- The interface is flexible and flexible callbacks can be designed.
- No hard coding
- Decoupling between modules
bad
- All the interface protocol files need to be in one place. Other modules depend on this module, but there will be no implementation code.
- Cumbersome to use, each invocation requires a service and a protocol.
CTMediator
Method of CTMediator target-action
- using
NSInvocation
Class, using a stringtargetName
And stringactionName
Let’s go to the correspondingid
andSEL
Type, useNSInvocation
Class makes a method calltypes
)
In my opinion, CT is still prone to problems and hard coding too many late changes can be troublesome.
optimal
- The API is simple and easy to learn.
- Into small
- Can solve the problem of calling between different classes
bad
- More hard coding,
- The compiler can’t check.
Componentization principle
- Principle of abstraction
- Stability principle
- The dependency is from top to bottom, and there is no dependency between groups.
Principle of abstraction
- The simplest criterion is that the APi called by the upper layer has not been changed for a long time.
- The ability to make abstract summaries
- Just like the Official Apple request every year, always use the API and don’t easily access the internal data structure.
Stability principle
- As long as it is stable, it is stable
- A stable module cannot depend on an unstable module
From top to bottom, groups and services do not depend on each other.
- Module design the upper layer can depend on the lower layer, the lower layer can not depend on the upper layer.
- Do not rely on horizontal modules.
- It is best to avoid top-down dependencies as much as possible in addition to the bottom-level indispensable dependencies
- Services do not depend on each other
conclusion
The componentization plan should be formulated according to the specific company size, number of people and development. For example, your company has only two people, development is very busy, join sub-business components, each do registration, binding, in fact, is too busy.
- For a project with a large number of people to maintain, the granularity of the separation must be fine. Perhaps This solution of Ali is more appropriate, with good decoupling and a little trouble to use.
- Items that are maintained by a small number of people can be broken up with great granularity, or even just into folders.
- For example, a
Model
, in multiple business use, 3 people can sink it to the bottom, the upper call. But with 300 people, you can only take them at a timejson
It is more appropriate to proceed from scratch.
There is no best plan, only according to the current staff, business, project comprehensive consideration of the selection of the plan.
Look at some schemes, in fact, you can take out some of their own feel good design fusion is also good.
Personal comparison suggests that the routing mode take BeeHive as the core, fuse MGJRouter, and then use lazy loading mode to initialize the module. And provides a pattern for non-lazy loading calls. When system memory leaks, you can use weak list to clean up memory and so on. There are always lots of new ideas.