我是Kotlin的初学者,我使用代码A来定义复杂的类MDetail,并使用代码B来创建一个对象aMDetail1,它可以工作.
但是数据结构太糟糕了,如果我像MD C一样在MDetail中包含一个新的数据类,比如ScreenDef,那么所有旧的代码都必须重写.
对于包含某些类的复杂类,是否有良好的数据结构?我希望将来数据构建可以轻松扩展!
代码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 wiFi:WiFiDef
- val aScreenDef:ScreenDef
- ...
- )
以下代码基于s1m0nw1所说的内容,我认为将来很容易扩展.谢谢!
还有其他更好的方法吗?
版本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 size: Long) : DeviceDef
- data class TimeLine(val Name: String): DeviceDef //Extend
- class MDetail(val _id: Long,1)
- val aTe = TimeLine("MyTimeline") //Extend
- val m = MDetail(7L,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
救命
我必须用open类替换接口,因为我无法从json字符串GSON反序列化MDetail对象.
但有趣的内联乐趣< reified T> getDevice():T {}无法返回正确的结果,我该怎么修改?谢谢!
- 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.
- interface DeviceDef
- data class BluetoothDef(val Status: Boolean = false) : DeviceDef
- data class WiFiDef(val Name: String,val size: Long) : DeviceDef
MDetail类可以使用这些设备的变量列表进行实例化,因此在添加新设备(如ScreenDef)时不需要进行任何修改:
- class MDetail(val _id: Long,val devices: List<DeviceDef>)
在MDetail中,您可以提供过滤这些设备的方法:
- class MDetail(val _id: Long,val devices: List<DeviceDef>) {
- inline fun <reified T> getDevice(): T {
- return devices.filterIsInstance(T::class.java).first()
- }
- }
现在,使用WifiDef非常简单:
- fun main(args: Array<String>) {
- val btD = BluetoothDef()
- val wfD = WiFiDef("")
- val m = MDetail(7L,listOf(btD,ScreenDef("",1)))
- println(m.getDevice<WiFiDef>())
- }
我希望这有帮助.如果没有,您可能需要提供有关MDetail应如何工作的更多详细信息.