一,概念
桥接模式为把抽象层次结构从实现中分离出来,使其可以独立变更,抽象层定义了供客户端使用的上层抽象接口,实现层次结构定义了供抽象层次使用的底层接口,实现类的引用被封装于抽象层的实例中,桥接就形成了.
桥接模式可以解决具有功能类似但又不完全相同的某种功能架构,为了能让实现更加灵活.
二,结构图
Abstraction:定义中所说的抽象部分,通常在这个对象里面,要维护一个实现部分的对象引用,在抽象对象里面的方法,需要调用实现部分的对象来完成。这个对象里面的方法,通常都是跟具体的业务相关的方法。在上面手机的例子中,可以理解为手机品牌接口;
Implementor:定义中所说的实现部分,这个接口不用和Abstraction里面的方法一致,通常是由Implementor接口提供基本的操作,而Abstraction里面定义的是基于这些基本操作的业务方法,也就是说Abstraction定义了基于这些基本操作的较高层次的操作。在上面手机的例子中,可以理解为手机软件接口(也可以是类);
RefinedAbstraction:抽象部分的具体实现,通常在这个对象里面,定义跟实际业务相关的方法,这些方法的实现通常会使用Abstraction中定义的方法,也可能需要调用实现部分的对象来完成。在上面手机的例子中,可以理解为具体的手机品牌,它实现了Abstraction接口;
ConcreteImplementatorA:实现部分的具体实现,在上面手机的例子中,可以理解为具体的手机软件,它实现了(或继承了) Implementor。
三,Demo演示
Abstraction(interface)
protocol PageDataProtocol {
//database
var dataBase: DataBaseProtocol?{get}
/// add one record
///
/// - Parameter record: record information
/// - Returns: whether success
func addOneRecord(record: Dictionary<String, Any>) -> Bool
/// delete one record
///
/// - Parameter recordId: record Id
/// - Returns: whether success
func removeOneRecord(recordId: String) -> Bool
/// get one page list data
///
/// - Parameters:
/// - pageNum: page's num
/// - pageSize: one page's record count
/// - Returns: page list
func pageListData(pageNum: Int, pageSize: Int) -> (Array<Dictionary<String, Any>>)?
}
RefineAbstraction
class HomePageData: PageDataProtocol {
var dataBase: DataBaseProtocol?
init(database: DataBaseProtocol) {
self.dataBase = database;
}
func addOneRecord(record: Dictionary<String, Any>) -> Bool {
if dataBase != nil {
return dataBase!.insertRecord(record: record)
}else{
print("database not exist")
return false;
}
}
func removeOneRecord(recordId: String) -> Bool {
if dataBase != nil {
return dataBase!.deleteRecord(recordId: recordId)
}else{
print("database not exist")
return false;
}
}
func pageListData(pageNum: Int, pageSize: Int) -> (Array<Dictionary<String, Any>>)? {
if dataBase != nil {
return dataBase!.selectRecords(start:pageNum,length:pageSize)
}else{
print("database not exist")
return nil;
}
}
}
Implementor
protocol DataBaseProtocol {
/// insert one record
///
/// - Parameter record: record
/// - Returns: whether success
func insertRecord(record: Dictionary<String, Any>) -> Bool
/// remove one record
///
/// - Parameter recordId: record id
/// - Returns: whether success
func deleteRecord(recordId: String) -> Bool
/// update one record
///
/// - Parameter record: record
/// - Returns: whether success
func updateRecord(record: Dictionary<String, Any>) -> Bool
/// query records
///
/// - Parameters:
/// - start: the start index
/// - length: one page's length
/// - Returns: records queried
func selectRecords(start: Int, length: Int) -> Array<Dictionary<String, Any>>
}
ConcrateImplementorA
class DataBaseA: DataBaseProtocol {
func insertRecord(record: Dictionary<String, Any>) -> Bool {
print("DB_A insert \(record)")
return true
}
func deleteRecord(recordId: String) -> Bool {
print("DB_A delete \(recordId)")
return true
}
func updateRecord(record: Dictionary<String, Any>) -> Bool {
print("DB_A update \(record)")
return true
}
func selectRecords(start: Int, length: Int) -> Array<Dictionary<String, Any>> {
print("DB_A query \(start) \(length)")
return [["name":"xiaoming"],["name":"xiaogang"]]
}
}
ConcrateImplementorB
class DataBaseB: DataBaseProtocol {
func insertRecord(record: Dictionary<String, Any>) -> Bool {
print("DB_B insert \(record)")
return true
}
func deleteRecord(recordId: String) -> Bool {
print("DB_B delete \(recordId)")
return true
}
func updateRecord(record: Dictionary<String, Any>) -> Bool {
print("DB_B update \(record)")
return true
}
func selectRecords(start: Int, length: Int) -> Array<Dictionary<String, Any>> {
print("DB_B query \(start) \(length)")
return [["name":"b_x"],["name":"b_g"]]
}
}
Client
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var homePageData = HomePageData(database: DataBaseA())
print(homePageData.pageListData(pageNum:0, pageSize:10))
homePageData = HomePageData(database: DataBaseB())
print(homePageData.pageListData(pageNum:0, pageSize:10))
}
}