我在做一个项目, 视图层使用的是抽象对象,而逻辑层是抽象的具体实现,在开发中期,发现很多问题,而最根本的问题是抽象与具体实现之间发生冲突。
要解决的问题:
任何事物在不同的人(角色)看来,都有不同的观点(关注点不一样),我们可以用多态的行为来解决,但在开发中引发的问题的我们想即想减少视图与逻辑的紧密度,同时又要保持其自身重定性和可扩展性,也就是逻辑的具体实现或改变不影响视图,但同时又要体现同一事物的多面性和发展性
举例:(C# 伪代码)
抽象父类
public abstrct class A { A.New( tag ); } //依据tag值 A.New方法返回不子类实例的抽象对象 ,
子类
private class A1:A { Name1{ get;set; } }
private A2:A { Name2{ get;set; } }.
.....后期依据需求会延伸出不同的子类
public abstrct class B (实现形式同上)
private class B1:B ,B2:B ...(子类)
抽象类与子类及子类之间有细节上的差异 , 另外父类与子类可能不存在于同一个物理位置 ( 就是所在的DLL不是同一个)
类之间的访问规则(父类之间、子类之间、父子类之间,同类型之间与不同类型之间):
1.在视图层只识别父类型,不知道子类型,
2.在逻辑层,
同一个类型下的父子类 之间可以相互访问或类型转换如A -> A1,A2.. ,B1->B,B2,B3...
但不同类型的父子关系只能通过抽象类进行交互(或说不同类型的子类是不能直接进行交互的),如:
B<->A , A1-> B,B1>A , 但不能 A1,A2->B1,B2 , B->A1
视图代码:
A a = A.New("A1");
B b = B.New( "B2" )
//需要对a与b内的某个拓展属性进行值的交互 ,
运行时的代码的样子: a.Name1 = b.Name2 ; 可能后期的子类还会出现其它新的属性和方法(不一定是Name1,Name2...不要固化思维或形而向上来才考虑问题),我是说在运行时的样子,但在编码时只知道A和B的类型,不知道其具体实现子类的扩展部分的元素(属性或方法),这种情况下如何实现抽象对象与抽象对象 (父对象与父对象)之间的交互??换句话说我需要确定具体的子类才可以交互。
原来我是实现个性化接口来实现 (每个子类实现唯一的接口),但这种方案行不通,最终还是间接的对子类型的依赖而且这种方案很笨不灵活,另外这个和反射没有关系,不要以为可以通过反射解决问题,一点关系都没有
最后,也许我在思路上出了问题,或也许进了牛角尖,但不管怎么样,还是请大家给点主意。多提点!
------解决方案--------------------
抽象不代表着没有内涵。你不要用什么“万能的”编程来想着做一些具体事情。
但凡能够抽象出实用、可扩展的系统的人,都是有着非常坚实的对各种具体实现的理论基础,然后才能抽象。如果看不出实际,那么所谓“抽象”就是“设计比较空洞”的借口。
此时,你应该把空洞放在一边,先做一些具体的工作。
------解决方案--------------------
抽象其实很朴实的东西。如果你喜欢做文章,或者有天花乱坠的功力,可能可以写出一些文章到大学生杂志获奖。但是我是站在程序开发角度,来看“何时、为何”抽象。我们进行程序设计,自然是希望代码少写一些,class或者接口少定义一些,这跟那些只是为了写个“看上去挺厉害的理论文章”的人出发点肯定不同。只是为了编程更有价值,才进行抽象扩展。绝不是为了教条而抽象。
------解决方案--------------------
额,玄学啊
居然在管理类需要依赖到具象子类了,这个设计已经不太友好了
不过已经成这样了,直能采用映射表去搞了。大体是这么描述把
1.需要在每一个对象上有一个获取扩展元数据的方法,这个你可以自己写一个,也可以直接使用反射获取自有属性列表
2.需要有一个注册表,去注册任意类型A到类型B的映射关系,大体上类似:
注册<A,B>(func<A,B> fun)
3.查询注册表,调用里面的convert运算委托
额,我怎么觉着我是在描述automapper/EmitMapper滴基本设计呢?
ps:作为抽象管理类本来应该只依靠抽象工作才符合依赖倒置原则,为啥你这个管理类会去依靠具体实现才能工作呢?如果是数据交互,那么数据交互本身就是一个抽象,他应该自成管理类,所以才有automapper/EmitMapper这类东西的出现
------解决方案--------------------
加多一个通用方法:
GetDataByName(string Name);
a.Name1 = b.Name2
可转换为:
a.Name1 = b.GetDataByName(Name2);
a就不在需要知道b的具体方法了
------解决方案--------------------
相互以来的对象间的交互可以call来call去,
但是,现实世界中确实存在而且是很普遍的:对象间在没有关联和依赖的情况下相互交互,
他们之间仅仅共同依赖通信的方式,
从设计层面,我觉得楼主的设计缺少对消息的描述,
从实现层面,微软的委托和事件为我们轻松地实现消息机制提供了可能
------解决方案--------------------
更正为:相互依赖
------解决方案--------------------
大手,我可否理解,依赖其实也是约束的表现呢
------解决方案--------------------
大手,我可否理解,依赖其实也是约束的表现呢
在UML中,依赖(dependency)的语义(比较含糊)大致是:
提供者(Supplier)的修改可能影响到消费者(Client)的修改,或者说如果没有提供者,消费者的语义就不完整;
OOAD中的消息用来描述和实现依赖
而你说的约束是什么,我不大清楚,
如果指的是UML中的规约specification或者对象约束OC,那是对对象的详细说明,肯定是两码事