How to merge the same processing code by property type, not by property name?
Here is the case:
struct GroupA{
let name: String
let memberNum: Int
var info: String{
var result = "\(memberNum) "
if memberNum > 1{
result = "members"
}
else{
result = "member"
}
return result " in \(name)"
}
}
- code to merge
struct GroupB{
let title: String
let peopleCount: Int
var info: String{
var result = "\(peopleCount) "
if peopleCount > 1{
result = "members "
}
else{
result = "member "
}
return result "in \(title)"
}
}
code usage example:
let a = GroupA(name: "haha ", memberNum: 5)
print(a.info)
let b = GroupB(title: "Bull", peopleCount: 6)
print(b.info)
Here is my solution:
struct GroupB{
let title: String
let peopleCount: Int
var converted: GroupA{
GroupA(name: title, memberNum: peopleCount)
}
}
- and usage:
let b = GroupB(title: "Bull", peopleCount: 6)
print(b.converted.info)
I think it is a little hard to use pop
reflection is an option
for the following example:
I think it is a little tough to use reflection
struct GroupC{
let title: String
let peopleCount: Int
let leaderName: String
}
Any other better idea?
PS:
- to merge
var info: String{ ... }
- "processing code" is
" sth ( number) sth (title) sth"
number in groupA is memberNum, number in groupB is peopleCount
title is much alike
just a simple demo pattern
CodePudding user response:
If I understood correctly, you don't want to merge, you want to factorize...
So:
struct InfoFormatting {
static func infos(from text: String, andNumber number: Int) -> String {
var result = "\(number) "
if number > 1 {
result = "number"
}
else {
result = "number"
}
return result " in \(text)"
}
}
I've created InfoFormatting, but it could be elsewhere, it depends on your architecture on where it would make more sense.
Then:
struct GroupA {
...
var info: String {
InfoFormatting.infos(from: name, andNumber: memberNum)
}
}
struct GroupA {
...
var info: String {
InfoFormatting.infos(from: title, andNumber: peopleCount)
}
}
That is the basic factorization.
Now, you could also use instead a protocol:
protocol InfoFormatter {
var infos: String { get }
}
extension InfoFormatter {
func infos(from text: String, andNumber number: Int) -> String {
var result = "\(number) "
if number > 1 {
result = "number"
}
else {
result = "number"
}
return result " in \(text)"
}
}
And make GroupA & GroupB compliant with it:
struct GroupA: InfoFormatter {
let name: String
let memberNum: Int
var info: String {
infos(from: name, andNumber: memberNum)
}
}
struct GroupB: InfoFormatter {
let title: String
let peopleCount: Int
var info: String {
infos(from: title, andNumber: peopleCount)
}
}
