问题描述
我是Kotlin的初学者,我使用代码A定义复杂的类MDetail
,并使用代码B创建对象aMDetail1
,它可以正常工作.
I'm a beginner of Kotlin, I use Code A to define a complex class MDetail
, and use Code B to create a object aMDetail1
, it can work.
但是数据结构很难扩展,如果像代码C那样在MDetail
中包含新的数据类(例如ScreenDef
),则必须重写所有旧代码.
But the data construction is too bad to expand, if I include a new data class such as ScreenDef
in MDetail
just like Code C, all old code have to be rewriten.
对于包含某些类的复杂类,是否有良好的数据构造?希望将来数据结构可以轻松扩展!
Is there a good data construction for a complex class which include some classes ? I hope to the data construction can be expansion easily in future!
代码A
data class BluetoothDef(val Status:Boolean=false)
data class WiFiDef(val Name:String, val Status:Boolean=false)
data class MDetail (
val _id: Long,
val bluetooth: BluetoothDef,
val wiFi:WiFiDef
)
代码B
var mBluetoothDef1= BluetoothDef()
var mWiFiDef1= WiFiHelper(this).getWiFiDefFromSystem()
var aMDetail1= MDetail(7L,mBluetoothDef1,mWiFiDef1)
代码C
data class BluetoothDef(val Status:Boolean=false)
data class WiFiDef(val Name:String, val Status:Boolean=false)
data class ScreenDef(val Name:String, val size:Long)
...
data class MDetail (
val _id: Long,
val bluetooth: BluetoothDef,
val wiFi:WiFiDef
val aScreenDef:ScreenDef
...
)
以下代码基于 s1m0nw1 所说的内容,我认为将来很容易扩展.谢谢!
The following code is based what s1m0nw1 said, I think it's easy to extend for future. Thanks!
还有其他更好的方法吗?
Is there other more better way?
版本1代码
interface DeviceDef
data class BluetoothDef(val Status: Boolean = false) : DeviceDef
data class WiFiDef(val Name: String, val Status: Boolean = false) : DeviceDef
data class ScreenDef(val Name: String, val size: Long) : DeviceDef
class MDetail(val _id: Long, val devices: MutableList<DeviceDef>) {
inline fun <reified T> getDevice(): T {
return devices.filterIsInstance(T::class.java).first()
}
}
class UIMain : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_main)
val btD = BluetoothDef(true)
val wfD = WiFiDef("MyWifi")
val xSc = ScreenDef("MyScreen", 1)
val m = MDetail(7L, mutableListOf(btD, wfD, xSc))
handleBluetoothDef(m.getDevice<BluetoothDef>())
handleWiFiDef(m.getDevice<WiFiDef>())
handleScreenDef(m.getDevice<ScreenDef>())
}
fun handleBluetoothDef(mBluetoothDef:BluetoothDef){ }
fun handleWiFiDef(mWiFiDef:WiFiDef){ }
fun handleScreenDef(mScreenDef:ScreenDef){ }
}
第2版代码(扩展)
interface DeviceDef
data class BluetoothDef(val Status: Boolean = false) : DeviceDef
data class WiFiDef(val Name: String, val Status: Boolean = false) : DeviceDef
data class ScreenDef(val Name: String, val size: Long) : DeviceDef
data class TimeLine(val Name: String): DeviceDef //Extend
class MDetail(val _id: Long, val devices: MutableList<DeviceDef>) {
inline fun <reified T> getDevice(): T {
return devices.filterIsInstance(T::class.java).first()
}
}
class UIMain : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_main)
val btD = BluetoothDef(true)
val wfD = WiFiDef("MyWifi")
val xSc = ScreenDef("MyScreen", 1)
val aTe = TimeLine("MyTimeline") //Extend
val m = MDetail(7L, mutableListOf(btD, wfD, xSc,aTe)) //Modified
handleBluetoothDef(m.getDevice<BluetoothDef>())
handleWiFiDef(m.getDevice<WiFiDef>())
handleScreenDef(m.getDevice<ScreenDef>())
handleTimeLine(m.getDevice<TimeLine>()) //Extend
}
fun handleBluetoothDef(mBluetoothDef:BluetoothDef){}
fun handleWiFiDef(mWiFiDef:WiFiDef){ }
fun handleScreenDef(mScreenDef:ScreenDef){ }
fun handleTimeLine(mTimeLine:TimeLine){} //Extend
帮助
我必须用开放类替换接口,因为我无法从json字符串GSON中反序列化MDetail对象.
I have to replace interface with open class because I can't unserialize MDetail object from json string GSON.
但是有趣的inline fun <reified T> getDevice(): T{ }
无法返回正确的结果,我该如何修改?谢谢!
but the fun inline fun <reified T> getDevice(): T{ }
can't return correct result, how can I modify? Thanks!
open class DeviceDef
data class BluetoothDef(val status:Boolean=false): DeviceDef()
data class WiFiDef(val name:String, val status:Boolean=false) : DeviceDef()
data class MDetail(val _id: Long, val deviceList: MutableList<DeviceDef>)
{
inline fun <reified T> getDevice(): T {
return deviceList.filterIsInstance(T::class.java).first()
}
}
推荐答案
我建议您执行以下操作:您的设备(Wifi,蓝牙等)应通过接口(至少作为标记)进行抽象,可以是名为DeviceDef
.
I suggest to do the following: Your units (Wifi, Bluetooth etc.) should be abstracted by an interface (at least as a marker), which could be named DeviceDef
.
interface DeviceDef
data class BluetoothDef(val Status: Boolean = false) : DeviceDef
data class WiFiDef(val Name: String, val Status: Boolean = false) : DeviceDef
data class ScreenDef(val Name: String, val size: Long) : DeviceDef
可以使用这些设备的变量列表实例化MDetail
类,以便在添加新设备(例如ScreenDef
)时无需修改:
The MDetail
class can be instantiated with a variable list of these devices, so that no modifications are needed when new devices, such as ScreenDef
, are added:
class MDetail(val _id: Long, val devices: List<DeviceDef>)
在MDetail
内,您可以提供一种过滤这些设备的方法:
Inside MDetail
, you can provide a method for filtering these devices:
class MDetail(val _id: Long, val devices: List<DeviceDef>) {
inline fun <reified T> getDevice(): T {
return devices.filterIsInstance(T::class.java).first()
}
}
现在,使用WifiDef
非常简单,例如:
Now, it's pretty simple to work with the WifiDef
for example:
fun main(args: Array<String>) {
val btD = BluetoothDef()
val wfD = WiFiDef("")
val m = MDetail(7L, listOf(btD, wfD, ScreenDef("", 1)))
println(m.getDevice<WiFiDef>())
}
我希望这会有所帮助.如果不是,则可能有必要提供有关MDetail
应该如何工作的更多详细信息.
I hope this helps. If not, it might be necessary that you provide more details on how MDetail
is supposed to work.
这篇关于如何设计一个复杂的类,其中包含一些类,以便将来在Kotlin中轻松扩展?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!