一个很典型的设计问题,真心求解,谢谢

DotCpp 2013-11-14 06:16:30
结构如下:



public class AView
{
public A A;

public virtual void Show(){ //显示A
}
}

public class AViewChild : AView
{
public Achild B;
public override void Show(){ //显示AChild
}
}

public class A
{
}

public class Achild : A
{
}


总感觉这个结构很不爽,但我现在能想到的解决方法只是能下面这种:

public class AView
{
public A A; //只保留这个

public virtual void Show(){ //显示A
}
}

public class AViewChild : AView
{
public override void Show(){
Achild test = A as AChild //强制转为Achild
}
}
...全文
345 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
OenAuth.Core 2013-11-20
  • 打赏
  • 举报
回复
引用 6 楼 sp1234 的回复:
如果你的 A、B 都是垃圾属性,仅仅“为了胡乱聚合而任意耦合在一起”,那么就如 #1 楼所示的,阉割了它就行了。
我的考虑是这样的: 1、AView是Winform的,在开发时,可以可视开发,可以方便调整A属性对应的控件位置排列等; 2、A是需要序列化的,所以把A和AView分开了, 3、如果把Show移到A中,因为A里要显示的变量(属性)有点多,不好调整对应控件的位置;
crack7 2013-11-20
  • 打赏
  • 举报
回复
我好像明白你的意识,其实你该使用接口来解决。 抽象出共用的A方法,也可以同时抽象出Aview类的共用接口。 IAVIEW:IA 然后 public class AViewChild:IAview { } 另外,不要使用多层继承。你需要反思下,你的AView是否和A的补充说明类,如果是,你得考虑下,是不是你分的太细了。 如果实在不行,那么需要考虑下能否抽象出一个基类+接口的设计。(个人推荐!) 如: public class AviewChild:A,IAView { } A作为基类,提供基础实现了的方法,IAView作为接口,补充相关额外方法。 我想,你应该想要的,就是着这种设计。
  • 打赏
  • 举报
回复
如果你硬要将 Achild 跟它的 show 方法割裂到两个class中去描述,那么你需要使用一个工厂方法,在 AView 的 show 方法中调用,返回属性 A 所适配的方法,例如
public class AView 
{
    public A A;
     
    public void Show(){  //显示A
         Action p = GetShowAction(A);
         p();
    }
}
这个 GetShowAction 如何实现,你可以自己想办法。这里只是说明,你的AView不是弄到什么子类去实现功能,而是在AView中就就地实现。
  • 打赏
  • 举报
回复
引用 5 楼 anglecloudy 的回复:
如果是用泛型的话,我在具体的操作时,不能用到AChild里面具体的属性
本来你得 AView 就根本不懂得各种Child的具体属性。一会儿插入一个A,一会儿插入一个B,......,你的设计根本没有抽象,而徒有其表地用了一个继承语法而已。
  • 打赏
  • 举报
回复
如果你的 A、B 都是垃圾属性,仅仅“为了胡乱聚合而任意耦合在一起”,那么就如 #1 楼所示的,阉割了它就行了。
OenAuth.Core 2013-11-15
  • 打赏
  • 举报
回复
引用 3 楼 caozhy 的回复:
[quote=引用 2 楼 wanghui0380 的回复:] 额,不知道你要干啥,所以就事论事的写
public class AView<T>
where T:A
{
  public T A;
     
    public virtual void Show(){  //显示A
    }
}

public class AViewChild : AView<Achild>
{
    public override void Show(){  
         //此处不用转换了,A字段已经是Achild类型了
    }
}
看lz的需求了,这样写严格来说AViewChild和AView没有继承关系了。[/quote] 如果是用泛型的话,我在具体的操作时,不能用到AChild里面具体的属性
DotCpp 2013-11-15
  • 打赏
  • 举报
回复
感谢楼上三位大大的回答: 实际我这是个很复杂的工程提取出来的抽象代码。 数据部分A,AChild是一系列的Model用用业务处理 显示部分AView AViewChild是一系列的Winform窗体(当初设计的人,竟然全部用Winform窗体继承⊙﹏⊙‖∣) 现在程序中就是一堆的Aview显示A,AViewChild显示AChild,AViewChildChild...显示AChildChild... 但为了简化代码,就把A设计成了AView的一个成员(就是我说的解决方法),这就造成了其它地方调用的时候都是:

AViewChild test = new AViewChild();
test.A = new AChild();
而在界面中都有:

class AViewChild{
   public void Show()
{
    AChild a = A as AChild;
}
  public void Test()
{
    AChild a = A as AChild....
}

后面的显示部分子类代码中也全都是这种AChildChild... a = A as AChildChild.. 感觉用的时候没什么问题,但我总觉得怪怪的。。。。
threenewbee 2013-11-14
  • 打赏
  • 举报
回复
引用 2 楼 wanghui0380 的回复:
额,不知道你要干啥,所以就事论事的写
public class AView<T>
where T:A
{
  public T A;
     
    public virtual void Show(){  //显示A
    }
}

public class AViewChild : AView<Achild>
{
    public override void Show(){  
         //此处不用转换了,A字段已经是Achild类型了
    }
}
看lz的需求了,这样写严格来说AViewChild和AView没有继承关系了。
wanghui0380 2013-11-14
  • 打赏
  • 举报
回复
额,不知道你要干啥,所以就事论事的写
public class AView<T>
where T:A
{
  public T A;
     
    public virtual void Show(){  //显示A
    }
}

public class AViewChild : AView<Achild>
{
    public override void Show(){  
         //此处不用转换了,A字段已经是Achild类型了
    }
}
rtdb 2013-11-14
  • 打赏
  • 举报
回复
因为看不出AView存在的必要性,所以再精简的话,就这样了:

public class A 
{
    public virtual void Show(){  //显示A
    }
}
 
public class AChild : A
{
    public override void Show(){  
    }
}
 

13,190

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 分析与设计
社区管理员
  • 分析与设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧