Com is the abbreviation of Component Object Model. Brew basically follows the COM component architecture. One advantage of the component architecture is that applications can evolve over time. In addition, components can be used to upgrade applications more conveniently and flexibly, such as application customization, Component Libraries, and distributed components.
COM was originally a software development technology developed by Microsoft to make software production in the computer industry more in line with human behavior. Under the com architecture, people can develop a variety of unique functional components and then combine them as needed to form a complex application system. The benefits are as follows: new components in the system can be replaced to upgrade and customize the system at any time; the same component can be reused in multiple application systems; the application system can be easily extended to the network environment; COM and language, platform-independent features allow all programmers to make full use of their talents and expertise to write component modules.
The services provided in the SDK are actually components formed by some small binary executable programs, which can provide services to applications, operating systems, and other components. Developing custom brew components (for example, brew extension class) is like developing dynamic and object-oriented APIs. Multiple brew objects can be connected to form an application or component system. In addition, components can be removed or replaced at runtime without being relinked or compiled.
Com is actually a programming method like structured programming and object-oriented programming. The advantages of using components directly come from the ability to dynamically insert or unload them from applications. To implement this function, all components must meet two conditions: first, components must be dynamically linked; second, they must be hidden (or encapsulated) internal implementation details. Dynamic Links are a crucial requirement for components, while message hiding is a necessary condition for dynamic links.
In general, brew can be connected with other components at runtime to form an application, which can be dynamically inserted or detached from the application. Brew hides (encapsulates) its internal implementation details. Brew-based applications are released in binary format and can be upgraded without interfering with existing users. Brew's custom extensions declare their presence in a standard way.
COM objects interact with each other through interfaces. An Interface contains the data structure of a group of functions. Through this data structure, code can call the functions of component objects. The interface defines a group member function. This group member function is all the available information that the component object exposes to the user. You can use this information to obtain the services provided by the component. Similar to using guid as the unique identifier of the interface in COM, brew uses a 4-byte unsigned integer called classid as the unique identifier.
Brew provides a set of fixed interfaces. Even if the implementation method changes in the future, as long as the interfaces between applications and component programs remain unchanged, no changes are required. Technically, an interface contains the data structure of a group of functions. Through this data structure, you can call the functions of a component. Similar to com, brew uses reference counting based on interface objects to control the interface's survival, and provides effective control measures for sharing unified interface objects among multiple programs. Generally, the reference counting technology includes three implementation methods: one is to use global reference counting, which can precisely control the lifetime of the entire application module; the second is to use a reference count trace interface for each interface, but for objects that implement multiple interfaces, the effect of doing so is that the resolution is too small, which will lead to the inability to precisely track the use of each interface, resulting in difficult management. The only benefit is to reduce resource consumption; the third is to use one reference count for each object to precisely control the object's survival, and to achieve a better balance between complexity and resource consumption. Method 3 of the brew interface reference count is to use reference count for each interface class or application.
The application uses a pointer to the interface data structure to call the interface member function, as shown in 4-5.
Figure 4-5: BrewApplication interface pointer
In fact, the interface pointer used by the application also points to a pointer, which points to the definition of a group of functions (that is, the interface function table, also known as the virtual function table, vtable ). The first parameter of each interface member function must be a pointer to the component type that defines this interface (refer to the process of simulating c ++ with C, in the class definition of C ++, the first parameter of each member function is implicit, that is, the this pointer automatically added by the compilation system. This is because the interface itself cannot exist independently, it must be attached to a COM component. Therefore, this pointer can provide the property information of the object instance. During the call, you can know that the COM object is being operated. In the figure, all pointers are defined before the circle edge box. The real implementation depends on the implementation provided by the COM component. For customers, it is enough to know what to call, however, for components, you must consider how to implement such functions. An interface is a bridge between a client program and a component program. The interface should be immutable, and a COM object should also support multiple interfaces.
For all objects of the same class, they have different data member storage areas, but share copies of the same member function, when different objects call member functions, this pointer is implicitly passed by the object to determine which object calls the member function. The implementation of interfaces is similar to that of data members in C ++. For pointers to virtual function tables, each interface pointer has its own copy, for virtual function tables that provide function implementation, the same copy is shared (Figure 4-6 ).
Figure 4-6: BrewVirtual function table in
The ishell_createlnstance method in brew uses the abstract factory mode of the object creation design mode. It provides interfaces for creating a series of related or mutually dependent objects without specifying their specific classes, in this way, only brew is provided.
And create a specific implementation according to the specific classid when necessary. Generally, the abstract factory mode has the following advantages:
(1) separating specific implementations and interfaces: you only need to specify different interfaces and classld to create interface objects successfully without worrying about the implementation;
(2) facilitate product module update: when a new module is updated, you do not need to change the program. Instead, you only need to replace the corresponding module implementation so that you can use the new module;
(3) It is conducive to product consistency. Due to the uniqueness of classid, you can create a specified object implementation without confusion in applications with numerous implementations.
The abstract factory model is difficult to support new types of products. It is eliminated in the brew design architecture. Due to the restart of the brew environment, the System-range classid is re-registered. Therefore, when a new category is added, you only need to provide a specified classid.
The application can be created successfully.