dimanche 7 février 2016

Swift: How can I improve this design?

I am learning Swift and Object Oriented Programming. I am new to design patterns and protocol oriented programming.

In my test code I have several related objects:

Security: the most important object that will be contained in the other ones.

AssetClass: Contains Securities objects

Watchlist: Contains Securities objects

Portolio: Contains Security and AssetClass objects

I want to be the most abstract as I can to avoid tight coupling.

The following code works but I am wondering how can it be improved. Do you see major weak points in my design?

import Foundation

protocol SecurityType{
    var code : String {get set}
    var name : String? {get set}
}

class Security:SecurityType{

    var code : String = ""
    var name : String?

    init(withCode aCode: String, andName aName: String?){
        self.code = aCode
        if let securityName = aName{
            self.name = securityName
        }
    }
}

protocol SecuritiesBasketType{
    var name : String {get set}
    var securities : [SecurityType]{get set}
    init()
}

extension SecuritiesBasketType{

    //Default Initializers

    init(withName aName: String){
        self.init()
        self.name = aName
    }

    init(withName aName: String, andSecurities securitiesArray:[SecurityType]){
        self.init()
        self.name = aName

        for aSecurity : SecurityType in securitiesArray{
            securities.append(aSecurity)
        }
    }

    mutating func addSecurity(security: SecurityType){
        securities.append(security)
    }
}

class AssetClass : SecuritiesBasketType{

    var name : String = ""
    var securities = [SecurityType]()
    required init(){}
}

class WatchList: SecuritiesBasketType{

    var name : String = ""
    var securities = [SecurityType]()
    required init(){}
}


class Portfolio{

    var name : String = ""
    var securities = [Security]()
    var assetClasses = [AssetClass]()
    required init(){}

    init(withName aName: String){
        self.name = aName
    }

    init(withName aName: String, andAssetClasses assetClasses:[AssetClass]){
        self.name = aName
        for assetClass in assetClasses{
            self.assetClasses.append(assetClass)
        }
    }

    init(withName aName: String, andAssetClasses assetClasses:[AssetClass], andSecurities securities:[Security]){

        self.name = aName

        for assetClass in assetClasses{
            self.assetClasses.append(assetClass)
        }

        for security in securities{
            self.securities.append(security)
        }
    }

}

//Creating Securities
var sMicrosoft = Security(withCode: "MSFT", andName: "Microsoft")
var sApple = Security(withCode: "AAPL", andName: "Apple")
var sJPMorgan = Security(withCode: "JPM", andName: "JP Morgan")
var sBankOfAmerica = Security(withCode: "BAC", andName: "Bank of America")
var sCaterpillar = Security(withCode: "CAT", andName: "Caterpillar")

//Creating Asset Classes
var acBanks = AssetClass(withName: "Banks", andSecurities: [sJPMorgan, sBankOfAmerica])
var acTechnology = AssetClass(withName: "Technology", andSecurities: [sMicrosoft, sApple])

//Creating Watchlists
var watchList1 = WatchList(withName: "List1", andSecurities: [sMicrosoft,sJPMorgan,sCaterpillar])
var watchList2 = WatchList(withName: "List2", andSecurities: [sBankOfAmerica,sApple])

//Creating Portfolios

var portfolio1 = Portfolio(withName: "Portfolio1", andAssetClasses: [acBanks,acTechnology])
var portfolio2 = Portfolio(withName: "Portfolio2", andAssetClasses: [acBanks, acTechnology], andSecurities: [sCaterpillar])

//Test

for ac : AssetClass in portfolio2.assetClasses{
    for s : SecurityType in ac.securities{
        print("\(s.name!)")
    }
}
for s : SecurityType in portfolio2.securities{
    print("\(s.name!)")
}

Aucun commentaire:

Enregistrer un commentaire