我理解的面向对象 (ObjectiveSql 实践)

用户头像
Braisdom
关注
发布于: 2020 年 09 月 12 日
我理解的面向对象(ObjectiveSql 实践)

原文:http://www.objsql.com/2020/09/14/oop_design/

最近参与一个项目,突然让我对“面向对象”有了重新的思考,一直以来,“面向对象”只存在于我的潜意识里,用Java 去设计系统时。先将问题域不断的细分,细分到一组相关的状态和行为能够合理的存在,这是我解决问题的基本逻辑,当然,上面一句话有太多的含糊不清的动作,例如:“细分”、“相关的状态”、“行为”、“合理”,这些词汇的包含了很多主观想法,仁者见仁,智者见智。

经济学里有一个概念称为“黑板经济学”,经济学是研究人类社会的发展规律(不仅仅是指经济规律),黑板经济学通常以一种纯粹理论化的思维和算法去思考人类社会的规律,看似完美,往往却和实际背道而驰,例如:公地的悲剧、慈善的逻辑等。在软件系统设计里,也有很多案例,J2EE 的悲剧、Python(网络效应) 的流行。所以软件系统设计应该更注重实用性的考量,理论可以提升认知的高度,而实际的工作应作一定程度的裁剪,应该以实践去反证理论。

本文是表达我对面向对象的理解,不得不谈到面向过程编程,其设计逻辑和面向对象基本一致。面向过程是将问题域分解后成为一个个Function,并将相关问题抽象成module、file等;而面向对象,则是分解为一个个Class,每个Class 中存在与该Class 相关的Method 和Field。面向过程强调的是逻辑和数据分离,而面向对象强调的是细分问题域中逻辑和数据有机的结合,形成问题域的一个可复用的整体,使程序能够被不断的复用,同样也可以通过封装将近似的问题模式复制至更多的领域,本质上是对面向过程编程的一种提升,将状态进行有限制的访问能够有效的避免低级错误的发生,但不能完全解决。在同一个Class中,不同的方法同样会导致状态的错乱,有待新的编程语言的出现,能够有效避免低级问题的出现,目前只能依赖程序员的智慧,这也是资深程序员存在的意义。

最近看了一些视频,是关于“充血模型”和“贫血模型”,还有ActiveRecord 模式等,如果站在更高的角度去理解,“贫血模型”就是C语言中的"struct",而充血模型就是Java 中的Class,到底是"struct" 还是Class 要站在系统不同位置去理解,两者都有存在的理由,只是“贫血模型”会隐式的存在。我的理解是“贫血模型”通常存在于数据传输,它只是一种传输协议定义,可以用在不同子系统或数据库之间的数据传递,当然“贫血模型”也不仅仅只有set 和get 方法,它应封装协议相关的行为(通常这些行为被封装在其它控制Class 中),Google 的ProtoBuffer 就是一个很好的实践。而“充血模型”和ActiveRecord,则是人为的一种定义,本质上它只是面向对象设计中基础的概念(状态和行为的封装),纯属制造概念。

面向对象的话题很大,我就以我项目中实际的问题简单介绍。

DomainModel

@DomainModel
public class Order {
private String no;
private Integer memberId;
private Float amount;
private Float quantity;
@Column(transition = SqlDateTimeTransitional.class)
private Timestamp salesAt;
@Relation(relationType = RelationType.BELONGS_TO)
private Member member;
@Relation(relationType = RelationType.HAS_MANY)
private List<OrderLine> orderLines;
@Transactional
@DataSourceName("test")
public static void makeOrder(Order order, OrderLine... orderLines) throws SQLException {
Order.create(order, false);
OrderLine.create(orderLines, false);
}
}

DomainModel 在项目中以Annotation 的形式存在,用于标识一个Class 是否为应用系统中的一个模型,模型中应该包括业务的状态和逻辑,同时也应描述描述该模型与其它模型的关系,具体解释如下:

  1. @DomainModel 会将该模型的状态与数据库中的表进行关联

  2. @Column(transition = SqlDateTimeTransitional.class) 定义该字段与数据库之间的转换方式

  3. @Relation(relationType = RelationType.BELONGS_TO) 定义Order 与Member 的关系

  4. @Transactional 标识该方法的数据操作会作为事务的形式提交

  5. @DataSourceName("test") 用于多数据源时指定该方法中的数据所属的数据库

Order 模型你可以称为ActiveRecord,也可以称为充血模型,但本质上它就是一个Java 的标准Class,符合面向对象设计的一般原则,将问题域细分,再封装,它只是将问题域中“订单”进行抽象,设计状态和行为,将问题域缩小至原子粒度,从业务逻辑概念进行推演不会产生歧义,使代码能够清晰描述逻辑和状态,将纯技术型代码分离,上述定义完成后,你可以这样直接使用:

Member member = Member.queryByPrimaryKey(1);



List<Member> members = Member.query("id between ? and ?", 10, 20);



int count = Member.count("id > ?", 10);

更多请参考:ObjectiveSql

发布于: 2020 年 09 月 12 日 阅读数: 137
用户头像

Braisdom

关注

ObjectiveSql 作者 2019.11.24 加入

将对世界的想法注入www.objsql.com,将对经验整合在ObjectiveSql 项目中。

评论

发布
暂无评论
我理解的面向对象(ObjectiveSql 实践)