protocol OrderPickUpViewModelFactoryProtocol {
    
}

extension OrderPickUpViewModelFactoryProtocol {
    
    fileprivate typealias TResult = OrderPickUpCellViewModelUpProtocol
    
    fileprivate func createRows(info: OrderDetailModel.ShuttleInfo, _: TDesc.Type, _: TLocation.Type, _: TSubDetail.Type, _: TTitle.Type) -> [TResult]
        where TDesc: OrderPickUpDetailDescCellViewModelProtocol,
        TLocation: OrderPickUpDetaiLocationCellViewModelProtocol,
        TSubDetail: OrderPickUpDetailSubDetailCellViewModelProtocol,
        TTitle: OrderPickUpDetailTitleCellViewModelProtocol
    {
        
        var rows: [TResult?] = []
        
        rows.append(TTitle(titleText: "AAA")))
        rows.append(TLocation(titleText: "BBB"))
        // .....        

        return rows.dropNil
    }
}

1.在工廠extension 內預設實作商業邏輯

 

/// For OrderDetail's detail page use
struct OrderPickUpViewModelCellFactory: OrderPickUpViewModelFactoryProtocol {
    static func createRows(navigationParameter: OrderPickUpDetailNavigationParameter) -> [OrderPickUpDetailCellViewModelProtocol]
    {
        let rows: [OrderPickUpCellViewModelUpProtocol] = OrderPickUpViewModelCellFactory().createRows(info: navigationParameter.shuttleInfo,
                                                                                                OrderPickUpDetailDescCellViewModel.self,
                                                                                                OrderPickUpDetaiLocationCellViewModel.self,
                                                                                                OrderPickUpDetailSubDetailCellViewModel.self,
                                                                                                OrderPickUpDetailTitleCellViewModel.self)
        
        guard let result = rows as? [OrderPickUpDetailCellViewModelProtocol] else {
            assert(false)
            return []
        }
        
        return result
    }
}

/// For OrderDetail use
struct OrderDetailPickUpViewModelCellFactory: OrderPickUpViewModelFactoryProtocol {
    
    static func createRows(shuttleInfo: OrderDetailModel.ShuttleInfo?) -> [OrderDetailCellViewModelProtocol]
    {

        guard let shuttleInfo = shuttleInfo else {
            return []
        }

        let rows: [OrderPickUpCellViewModelUpProtocol] = OrderPickUpViewModelCellFactory().createRows(info: shuttleInfo,
                                                                                                OrderDetailPickUpDetailDescCellViewModel.self,
                                                                                                OrderDetailPickUpDetaiLocationCellViewModel.self,
                                                                                                OrderDetailPickUpDetailSubDetailCellViewModel.self,
                                                                                                OrderDetailPickUpDetailTitleCellViewModel.self)
        
        guard let result = rows as? [OrderDetailCellViewModelProtocol] else {
            assert(false)
            return []
        }
        
        return result
    }
}

2.實際的工廠(struct)中來填入指定的type,以方便page呼叫

 

OrderDetailPickUpViewModelCellFactory.createRows(shuttleInfo: model.data.summary.shuttleInfo)

3.Page中呼叫專用的工廠取得塞好值的CellViewModel

 

需求是在個頁面都有90%相同的UI,但是兩頁protocol需實作的東西不同,只有些地方相同,

所以後來想到用泛型來解決這個問題,並用工廠模式產生instance,

不過不同頁面會用不同工廠,所以就變成了抽象工廠。

在工廠extension 內預設實作商業邏輯,

並在實際的工廠(struct)中來填入指定的type,

以方便page呼叫

 

創作者介紹
創作者 小賢 的頭像
小賢

小賢的部落格

小賢 發表在 痞客邦 留言(0) 人氣()