美文网首页
设计模式(六) Adapter

设计模式(六) Adapter

作者: jianshudxw | 来源:发表于2019-07-05 11:41 被阅读0次

定义:将一个接口转换成客户希望的另一个接口,适配器模式使得原本不能一起工作的类,可以一起工作。

比如原本的类

struct Employee {
    var name: String;
    var title: String;
}

protocol EmployeeDataSource {
    var employees: [Employee] { get };
    func searchByName(name: String) -> [Employee];
    func searchByTitle(title: String) -> [Employee];
}

class DataSourceBase: EmployeeDataSource {
    var employees = [Employee]();
    
    func searchByName(name: String) -> [Employee] {
        return search(selector: { (e) -> Bool in
            return e.name.range(of: name) != nil;
        });
    }
    
    func searchByTitle(title: String) -> [Employee] {
        return search(){(e) -> Bool in
            return e.title.range(of: title) != nil;
        }
    }
    
    private func search(selector:((Employee) -> Bool)) -> [Employee] {
        var results = [Employee]();
        for e in employees {
            if selector(e) {
                results.append(e);
            }
        }
        return results;
    }
}

class SalesDataSource: DataSourceBase {
    override init() {
        super.init();
        employees.append(Employee(name: "Alice", title: "VP of Sales"));
        employees.append(Employee(name: "Bob", title: "Account Exec"));
    }
}

class DevelopmentDataSource: DataSourceBase {
    override init() {
        super.init();
        employees.append(Employee(name: "Joe", title: "VP of Developer"));
        employees.append(Employee(name: "Pepe", title: "Developer"));
    }
}

class SearchTool {
    enum SearchType {
        case NAME;
        case TITLE;
    }
    private let sources: [EmployeeDataSource];
    init(dataSources: EmployeeDataSource...) {
        self.sources = dataSources;
    }
    
    var employees: [Employee] {
        var results = [Employee]();
        for source in sources {
            results += source.employees;
        }
        return results;
    }
    
    func search(text: String, type: SearchType) -> [Employee] {
        var results = [Employee]();
        for source in sources {
            results += type == SearchType.NAME ? source.searchByName(name: text) : source.searchByTitle(title: text);
        }
        return results;
    }
    
}

let search = SearchTool(dataSources: SalesDataSource(),DevelopmentDataSource());
print("--List--");
for e in search.employees {
    print("name: \(e.name)")
}

print("--Search--")
for  e in search.search(text: "VP", type: SearchTool.SearchType.TITLE) {
    print("Name: \(e.name), Title: \(e.title)");
}

新加的不兼容的类

class NewCoStaffMember {
    private var name: String;
    private var role: String;
    init(name: String, role: String) {
        self.name = name;
        self.role = role;
    }
    func getName() -> String {
        return name;
    }
    func getJob() -> String {
        return role;
    }
}

class NewCoDirectory {
    private var staff:[String: NewCoStaffMember];
    init() {
        staff = ["Hans": NewCoStaffMember(name: "Hans", role: "Corp Counsel"),
                 "Greta": NewCoStaffMember(name: "Greta", role: "VP, Legal")];
    }
    func getStaff() -> [String: NewCoStaffMember] {
        return staff;
    }
}

适配器模式 使得可以一起工作

extension NewCoDirectory : EmployeeDataSource {
    var employees: [Employee] {
        return getStaff().values.map{ sv -> Employee in
            return Employee(name: sv.getName(), title: sv.getJob());
        }
    }
    
    func searchByName(name: String) -> [Employee] {
        return createEmployees(filter: { (sv: NewCoStaffMember) -> Bool in
            return sv.getName().range(of: name) != nil;
        })
    }

    func searchByTitle(title: String) -> [Employee] {
        return createEmployees(filter: { (sv: NewCoStaffMember) -> Bool in
            return sv.getJob().range(of: title) != nil;
        })
    }
    
    private func createEmployees(filter filterClosure:((NewCoStaffMember) -> Bool)) -> [Employee] {
       return getStaff().values.filter(filterClosure).map { entry -> Employee in
            return Employee(name: entry.getName(), title: entry.getJob());
        } ;
    }
}

let search = SearchTool(dataSources: SalesDataSource(),DevelopmentDataSource(), NewCoDirectory());
print("--List--");
for e in search.employees {
    print("name: \(e.name)")
}

print("--Search--")
for  e in search.search(text: "VP", type: SearchTool.SearchType.TITLE) {
    print("Name: \(e.name), Title: \(e.title)")
}
  • 这里用extension方式实现的
  • 也可使用其他技术,比如,组合的方式。定义一个新类,包含NewCoDirectory对象。实现EmployeeDataSource协议即可。

相关文章

  • 设计模式(六) Adapter

    定义:将一个接口转换成客户希望的另一个接口,适配器模式使得原本不能一起工作的类,可以一起工作。 比如原本的类 新加...

  • 11.3设计模式-适配器-详解

    设计模式-适配器adapter模式 adapter模式详解 adapter模式在android中的实际运用1.li...

  • 浅谈设计模式之适配器模式

    适配器模式(Adapter Pattern) 概述: 在设计模式中,适配器模式(adapter pattern)有...

  • 设计模式-adapter设计模式

    效果图 1.定义 将一种对象适配成另一种对象 2.示例 3.使用 listview的适配器 4.总结 1.适配器模...

  • Adapter模式(设计模式)

    对象适配器模式(使用委托的适配器) 个人理解 用一个比喻来描述比较好,比如:中国现在用电的标准电压是220V交流电...

  • 设计模式-Adapter

    一,Adapter模式详解 适配器模式定义将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类一起...

  • Adapter 设计模式

    adapter 模式详解 类的适配器模式 把适配的类的 API转换为目标类的API。 对象适配器对象的适配器模式 ...

  • 浅谈GoF23设计模式-“Adapter”模式

    “Adapter”模式为结构型设计模式,C#当中主要使用对象适配器。“Adapter”模式定义:将一个类的接口转换...

  • 简说设计模式之适配器模式

    前言:对于设计模式基础概念可以去看[简说设计模式之设计模式概述] 一、什么是适配器模式 适配器模式(Adapter...

  • Typescript 适配器模式(Adapter)

    标签: 前端 设计模式 适配器模式 typescript Adapter 请仔细阅读下面代码,理解其中的设计理念。...

网友评论

      本文标题:设计模式(六) Adapter

      本文链接:https://www.haomeiwen.com/subject/otkshctx.html