继承和组合对应着客观事物的组织结构形态,具体的说:
访问权限可以由不同语言的访问限定符进行不同粒度的控制,而继承和组合最大的区别在于继承体系中子类对父类protect 方法的override能力(在子类实现中可能会调用super的相同方法)
对于继承和组合对代码结构的优化,首先开始的是由客观事物形态决定的继承关系,在子类继承父类的同时,自身有很多功能的定制
将子类对每个功能的定义进行依赖关系梳理,每个功能以高内聚低耦合的组合方式在子类中使用,可以考虑使用android lifecycle这种观察者模式将每个功能类的对关键事件(生命周期)的监听进行分发,降低其在子类中的耦合,一行代码完成一个功能
这种优化方式已经可以使得项目代码逻辑清晰,对于需要某个高内聚功能时,可以选择直接继承(有合适的父类时)或者组合各个功能类进行实现,从而解决无法多继承但同时需要两个不同的父类功能时的问题
很多设计模式和设计思想都是为了组合代替继承,又如语言层面对委托的支持(kotlin delegate, dart mixin)。通过上面对组织结构形态的分析,继承和组合最大的区别在于继承体系中子类对父类protect 方法的override能力,因此函数式编程思想(kotlin, dart中的函数变量传递,java中则对应着lambda表达式或者单方法interface)解决这个问题,在flutter中更是推荐组合代理继承,所有widget只要继承StatefulWidget或者StatelessWidget并进行功能组合即可
graph LR
subgraph 被别人组合获取能力: 要求两者对外具有相同的接口能力抽象,通过代理转发
MyViewWantsToBeCenter-->|继承|View
MyViewWantsToBeCenter-->|组合|Center("wrap it in a Center widget")
end
subgraph 组合别人获取能力
子类-->|继承|父类
包裹者-->|包裹|被包裹者
end
通过传递方法fun实现给被包裹类,在被包裹类中进行fun的调用,达到类似子类override父类的能力。如果要实现类似子类调用super同签名方法实现的功能,
从被包裹类到包裹类层层包裹方法实现:
可以将被包裹类中的同签名fun作为额外的(原方法签名参数列表后新增一个)参数,让外部传递新的参数列表给被包裹类,被包裹类通过调用fun1时传递自身实现让包裹类拥有类似子类调用super同签名方法实现的能力,如果包裹类没有传递fun1,可以直接调用fun
class BeWrapperedA(Fun1 funA)
otherFun() {
funA(param1, param2, fun)
}
fun(param1, param2) {
}
Fun1(param1 a, param2 b, fun(param1, param2) c)
------------------------------------------------
class BeWrapperedB(Fun1 funB)
BeWrapperedA((a, b, c) -> {funB(a, b, (a, b) -> (Fun1(a, b, c))))})
Fun1(param1 a, param2 b, fun(param1, param2) c) {
c(a , b) //相当于调用super(a, b)
a + b;//自定义逻辑
}
正向思维,从包裹类到被包裹类,按需调用方法,类似代理等设计思想,都实现接口,按需调用,类似flutter的StatefulWidget的一级子类,通过build方法约定从包裹类最外层开始向内调用被包裹类的方法实现
在面临多继承需求时,如果所需要功能父类没有很好的封装功能并进行组合,导致自身没有组合对象,因此可以通过函数式思想优化,组合代替继承,完成功能的包裹和组合
https://flutter.dev/docs/resources/architectural-overview#widgets
const RaisedButton({
Key key,
@required VoidCallback onPressed,
@override
Widget build(BuildContext context) {
return RawMaterialButton(
onPressed: onPressed,
class RawMaterialButton extends StatefulWidget {
/// Called when the button is tapped or otherwise activated.
///
/// If this is set to null, the button will be disabled, see [enabled].
final VoidCallback onPressed;
class _RawMaterialButtonState extends State<RawMaterialButton> {
@override
Widget build(BuildContext context) {
final Widget result = Focus(
child: ConstrainedBox(
child: Material(
child: InkWell(
onTap: widget.onPressed,
class Container extends StatelessWidget {
@override
Widget build(BuildContext context) {
Widget current = child;