Conventions and patterns for multi-platform development
Conventions and patterns for multi-platform development
|
Chromium is a large and complex cross-platform product. We try to share as much code as possible between platforms, while implementing the UI and OS integration in the most appropriate way for each. While this gives a better user experience, it adds extra complexity to the code. This document describes the recommended practices for keeping such cross-platform code clean.
We use a variety of different file naming suffixes to indicate when a file should be used:
The separate front-ends of the browser are contained in their own directories:
The Coding Style page lists some stylistic rules affecting platform-specific defines.
How to separate platform-specific codeSmall platform differences: #ifdefsWhen you have a class with many shared functions or data members, but a few differences, use #ifdefs around the platform-specific parts. If there are no significant differences, it's easier for everybody to keep everything in one place.
Small platform differences in the header, larger ones in the implementation: split the implementationThere may be cases where there are few header file differences, but significant implementation differences for parts of the implementation. For example, base/waitable_event.h defines a common API with a couple of platform differences.
With significant implementation differences, the implementation files can be split. The prevents you from having to do a lot of #ifdefs for the includes necessary for each platform and also makes it easier to follow (three versions each of a set of functions in a file can get confusing). There can be different .cc files for each platform, as in base/waitable_event_posix.cc that implements posix-specific functions. If there were cross-platform functions in this class, they would be put in a file called base/waitable_event.cc.
Complete platform implementations and callers: separate implementationsWhen virtually none of the implementation is shared, implement the class separately for each platform in separate files.
If all implementations are in a cross-platform directory such as base, they should be named with the platform name, such as FooBarWin in base/foo_bar_win.h. This case will generally be rare since files in these cross-platform files are normally designed to be used by cross-platform code, and separate header files makes this impossible. In some places we've defined a commonly named class in different files, so PlatformDevice is defined in skia/ext/platform_device_win.h, skia/ext/platform_device_linux.h, and skia/ext/platform_device_mac.h. This is OK if you really need to refer to this class in cross-platform code. But generally, cases like this will fall into the following rule.
If the implementations live in platform-specific directories such as chrome/browser/ui/cocoa or chrome/browser/ui/views, there is no chance that the class will be used by cross-platform code. In this case, the classes and filenames should omit the platform name since it would be redundant. So you would have FooBar implemented in chrome/browser/ui/cocoa/foo_bar.h.
Don't create different classes with different names for each platform and typedef it to a shared name. We used to have this for PlatformCanvas, where it was a typedef of PlatformCanvasMac, PlatformCanvasLinux, or PlatformCanvasWin depending on the platform. This makes it impossible to forward-declare the class, which is an important tool for reducing dependencies.
When to use virtual interfacesIn general, virtual interfaces and factories should not be used for the sole purpose of separating platform differences. Instead, it should be be used to separate interfaces from implementations to make the code better designed. This comes up mostly when implementing the view as separate from the model, as in TabContentsView or RenderWidgetHostView. In these cases, it's desirable for the model not to depend on implementation details of the view. In many cases, there will only be one implementation of the view for each platform, but gives cleaner separation and more flexibility in the future.
In some places like TabContentsView, the virtual interface has non-virtual functions that do things shared between platforms. Avoid this. If the code is always the same regardless of the view, it probably shouldn't be in the view in the first place.
Implementing platform-specific UIIn general, construct platform specific user interface elements from other platform-specific user interface elements. For instance, the views-specific class BrowserView is responsible for constructing many of the browser dialog boxes. The alternative is to wrap the UI element in a platform-independent interface and construct it from a model via a factory. This is significantly less desirable as it confuses ownership: in most cases of construction by factory, the UI element returned ends up being owned by the model that created it. However in many cases the UI element is most easily managed by the UI framework to which it belongs. For example, a views::View is owned by its view hierarchy and is automatically deleted when its containing window is destroyed. If you have a dialog box views::View that implements a platform independent interface that is then owned by another object, the views::View instance now needs to explicitly tell its view hierarchy not to try and manage its lifetime.
e.g. prefer this:
to this:
Sometimes this latter pattern is necessary, but these occasions are rare, and very well understood by the frontend team. When porting, consider converting cases of the latter model to the former model if the UI element is something simple like a dialog box.
|
Conventions and patterns for multi-platform development的更多相关文章
- 环境初始化 Build and Install the Apache Thrift IDL Compiler Install the Platform Development Tools
Apache Thrift - Centos 6.5 Install http://thrift.apache.org/docs/install/centos Building Apache Thri ...
- Head First Design Patterns
From Head First Design Patterns. Design Principle: Idnetify the aspects of your application that var ...
- Linux之一次性安装开发工具:yum groupinstall Development tools
[spark@sparksinglenode ~]$ yum grouplist | moreLoaded plugins: fastestmirror, refresh-packagekit, se ...
- Learning PHP Design Patterns
Learning PHP Design Patterns CHAPTER 1 Algorithms handle speed of operations, and design patterns ha ...
- Customize Netbeans Platform Splash Screen and About Dialog
原帖一直打不开,通过谷歌翻译找到的 http://blogs.kiyut.com/tonny/2007/10/18/customize-netbeans-platform-splash-screen- ...
- Best Open Source Software
Best Open Source Software Open Source, Software, Top The promise of open source software is best qua ...
- BlackArch-Tools
BlackArch-Tools 简介 安装在ArchLinux之上添加存储库从blackarch存储库安装工具替代安装方法BlackArch Linux Complete Tools List 简介 ...
- 所有selenium相关的库
通过爬虫 获取 官方文档库 如果想获取 相应的库 修改对应配置即可 代码如下 from urllib.parse import urljoin import requests from lxml im ...
- Android NDK开发指南---Application.mk文件和android.mk文件
https://android.googlesource.com/platform/development/+/donut-release/ndk/docs/OVERVIEW.TXT https:// ...
随机推荐
- 2015 Multi-University Training Contest 3 hdu 5316 Magician
Magician Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- Samurai's Stroke
题目链接 题意: 一个长度为L的木棍,有n个支点支撑,每一个点是一个int数.表示距离木棍左端点的距离.求在那些位置将木棍劈开能够使得至少有一个木棍掉下去,输出这些位置的长度 3 ≤ l ≤ 109; ...
- 好的Unix工具的九大启发
我们每天都在使用前人开发的各种工具. 一款好的工具能无缝地融入到你的工作环境中,而一款"差"的工具经常须要花费额外的精力才干集成到你的工作环境中. (注意:这里的差是指用户体验方面 ...
- android中的AlertDialog具体概述
android的AlertDialog具体解释 AlertDialog的构造方法所有是Protected的.所以不能直接通过new一个AlertDialog来创建出一个AlertDialog. 要创建 ...
- 页面头部带loading进度指示的jQuery滚动页面特效
这是一款非常有用且效果非常酷的jQuery页面头部带loading进度指示的滚动页面特效. 该特效在页面滚动的时候页面头部有Loading进度条指示当前页面滚动的位置,这能够让用户知道当前阅读的地方距 ...
- 12、NIO、AIO、BIO二
一.NIO2快速读写文件 写完之后记得flush一下,NIO2不能自行创建文件,需要在文件中判断一下. package com.zxc.L; import org.junit.Test; import ...
- Tomcat的安装跟配置
安装Tomcat的步骤:1)安装好JDK2)把tomcat-7.0.30软件解压到本地硬盘3)设置环境变量:JAVA_HOME: C:\Program Files\Java\jdk1.7.0_04To ...
- PHP 二维数组去掉重复值并保持原结构
PHP 二维数组去掉重复值并保持原结构 直接上代码,解释很详细 //二维数组去掉重复值 function arrunique($a){ foreach($a[0] as $k => $v){ / ...
- 2.mongoDB 介绍(特点、优点、原理)
转自:https://www.cnblogs.com/hoojo/archive/2011/06/01/2066119.html 介绍:MongoDB是一个基于分布式文件存储的数据库.由C++语言编写 ...
- 启动hadoop遇到的datanode启动不了
从截图上看是datanode的clusterID 和 namenode的clusterID 不匹配. 解决办法: 根据日志中的路径,cd /hadoop/data/dfs/ 能看到 data和name ...