智能领域对象设计

10-07-04 cuwkuhaihong
我们重新审视的以下JAVA的Object的对象,其中包含了两个特殊的方法,equals和clone,从这两个方法我们可以看出,在面向对象的程序设计中,对象的设计不能紧紧参考其所描述的对象,而不是不可添加其他便于对象活动的行为的。为什么会有这样的结论,equals的判断两个对象是否相同,这种对象与对象之间相同与否的问题,是只有具备智能的动物或者智能机器人才有的能力做这样的结论,大多数的对象是没有此能力的,clone就不必说了。故做对象设计不必严格遵守现实,现在大家在写程序的时候经常创建的javabean,只有setter和getter,也是一种无活力对象,只具备传递数据的能力,而且要配合对应的service方法才完成工作,service类就是一个方法集,严格来讲不是面向对象编程。

我们不必在意是否遵守了面向对象的设计方法,能提高生产力的方法,就是好方法。我尝试了一种新的设计方法,看是否可以提高生产力,大家不妨看看。

第一,Object对象已经具备equals和clone了这样的智能方法了,我们不妨再让这个object聪明点,给他提供记忆联想功能。接下来的两点详细说明。

第二,很多对象是需要存储的,对象储取能力不需要外部提供,而是继承提供存取能力的对象,这就好像说,你家养的狗狗可以自己到宠物管理机构登记和变更它自己的信息了(听着都轻松),不用那么现实。

第三,世界上任何对象都不是孤立存在,而是相互影响的,存在因果关系的,一种原因能产生什么样的结果,有些是一定的,有的却不一定,对象之间的关联,有些情况是联系紧密的、有些是疏散的,对象具备自己的关系网络。如你目睹一起三车相撞的交通事故,其中一人的腿的伤势给你印象深刻,以后任何人提起腿受伤,你都会想起那个人,接着想起亲眼目睹那次事故,你还可以想到这起事故具体是如何发生的,即有点到面,有面到体,逐步深入。下面是我的一个对象设计(源代码https://sourceforge.net/projects/thinery/files/try.zip/download

):


public abstract class IObject extends Observable {
	protected static boolean inited = false;
	
	public IObject() {
		….....
		
	}
	
	/**
	 * 对象第一此加载的时候初始化所有的监听器,该类的活动如果影响的其他对象
	 * 都可以在监听器完成因果传递,监听器统一配置在一个叫:[子类名称]_lstnr.properties
	 * 的配置文件中,如果对象找不到该文件,会认为没有监听器
	 */
	static Map<String, Observer> observers = new HashMap();

	/**
	 * 把对象自身持久的数据库的方法。子类可以根据类的情况,重写该方法。 如该类是一对一,
         *一对多的,想把关联对象一起存储,就需要重写该方法
	 */
	public abstract void remember();

	/**
	 * 删除此对象对应的数据库记录。 恰如我们忘记一件事物
	 */
	public abstract void forget();

	/**
	 * 用于更新数据库记录,需要更新对象的某一个属性时,用到此方法。 恰如我们需要更新对一件事物的记忆。
	 * 我们每隔三天去看一个正在建设的高楼,那么大脑每次都要更新高楼的高度。
	 * 
	 * @param updateFields
	 *            属性的名称,如果你更改username的值,那么这个参数就应该是username, 注意不是username的值
	 */
	public abstract void updateMemory(String... updateFields);

	/**
	 * 这是一个最自由的方法,该类方法名称意为”联想“,一般默认实现是查询相关对象。 
         * 如:我们通过宝马,联想到奔驰和奥迪。
	 * 如果这是一个事件对象,那么你可以让他想到与这个事件相关的任何东西。
	 * 
	 * @param params
	 *            任何对象
	 * @return
	 */
	public abstract List associate(Object... params);

	/**
	 * 根据主键数据库中获取自身的全部信息
	 * 
	 * @param id
	 * @return
	 */
	public abstract void obtainMe();
}
<p>

         

6
cuwkuhaihong
2010-07-04 19:59
我基于Thin完成一个实现,Thin是一种基于key-value的持久层框架,简单易用,体现持久本质。在此不再详述。大家可以参考源代码:http://sourceforge.net/projects/thinery/

public class ThinObject extends IObject {
	protected static Logger log = Logger.getLogger(IObject.class);
	static {
		/**
		 * 这里建立了一种约定,一种对象的属性名与数据库中表字段名相互转换的约定。
		 */
		KVUtils.mappingRule = new AnnotationMappingRule();
	}

	/**
	 * 在配置文件中加载自定义的SQL,存放在此处以供该类的方法使用
	 * 
	 */
	static Properties sqls = new Properties();

	transient protected BeanTable beanTable;

	/**
	 * 把该类的所有属性,全部转化成key-value用于存储
	 * 
	 * @return
	 * @throws Exception
	 */
	protected Map<String, Object> toKeyValue() throws Exception {
		return KVUtils.toKeyValue(this);
	}

	protected Field hasPrimary() {
		Field[] fields = getClass().getDeclaredFields();
		for (Field field : fields) {
			Primary pry = field.getAnnotation(Primary.class);
			if (pry != null) {
				return field;
			}
		}
		return null;
	}

	/**
	 * 该设计的持久方式采用的是'thin',<a
	 * href="http://sourceforge.net/projects/thinery/">thin</a>
	 * 是基于key-value的持久层框架,简单,易用,透析持久本质; 默认采用约定优先,注解在后的映射方式,还支持定义映射。
	 * 
	 * @return
	 * @throws SQLException
	 */
	protected BeanTable getBeanTable() throws SQLException {

		if (beanTable == null) {
			BeanTableName btn = this.getClass().getAnnotation(
					BeanTableName.class);
			String tableName = btn.name();
			String schema = btn.schema();
			if ("".endsWith(schema)) {
				beanTable = ThinContext.getThinContext()
						.getBeanTable(tableName);
			} else {
				beanTable = ThinContext.getThinContext(schema).getBeanTable(
						tableName);
			}
		}

		return beanTable;

	}

	public ThinObject() {
		if (!inited) {
			try {
				initSQLProperties();
			} catch (Exception e) {
				e.printStackTrace();
			}
			inited = true;
		}

	}

	private void initSQLProperties() throws IOException {
		InputStream inStream = this.getClass().getClassLoader()
				.getResourceAsStream(this.getThisName() + "_sql.properties");
		if (inStream != null) {
			sqls.load(inStream);
		}
	}

	@SuppressWarnings("unchecked")
	protected List toBeans(List<Map<String, Object>> keyvalues)
			throws Exception {
		return KVUtils.toBeans(keyvalues, this.getClass());
	}

	/**
	 * 把对象自身持久的数据库的方法。子类可以根据类的情况,重写该方法。 如该类是一对一,一对多的,想把关联对象一起存储,就需要重写该方法
	 * 
	 * @throws RuntimeException
	 */
	public void remember() throws RuntimeException {
		try {
			this.getBeanTable().addOrUpdate(toKeyValue());

			this.setChanged();
			this.notifyObservers();
		} catch (Exception e) {
			log.error("记忆出现异常!", e);
			throw new RuntimeException(e);

		}
	}

	/**
	 * 删除此对象对应的数据库记录。 恰如我们忘记一件事物
	 */
	public void forget() {
		try {
			this.getBeanTable().delete(toKeyValue());
			
			this.setChanged();
			this.notifyObservers();
		} catch (Exception e) {
			log.error("删除记录出现异常", e);
			throw new RuntimeException(e);
		}

	}

	public void updateMemory(String... updateFields) {
		try {
			Map<String, Object> keyvalues = new HashMap<String, Object>();
			for (String name : updateFields) {
				KVUtils.mappingRule.setDBColumn(this, this.getClass()
						.getDeclaredField(name), keyvalues);
			}

			Field primaryField = hasPrimary();
			if (primaryField != null
					&& !keyvalues.containsKey(primaryField.getName())) {
				KVUtils.mappingRule.setDBColumn(this, primaryField, keyvalues);
			}

			this.getBeanTable().update(keyvalues);

			this.setChanged();
			this.notifyObservers();
		} catch (Exception e) {
			log.error("更新存储出现异常", e);
			throw new RuntimeException(e);
		}
	}

	@SuppressWarnings("unchecked")
	public List<Object> associate(Object... params) {
		try {
			Criterion[] criterions=toCriterion(params);
			
			return this.toBeans(this.getBeanTable().get(criterions));
		} catch (Exception e) {
			log.error("查询记录出现异常", e);
			throw new RuntimeException(e);
		}
	}

	private Criterion[] toCriterion(Object... params) {
		Criterion[] criterions = new Criterion[params.length];
		for(int i=0;i<params.length;i++){
			criterions[i] = (Criterion)params[i];
		}
		return criterions;
	}

	public void obtainMe() {
		try {
			Field field = this.hasPrimary();
			Object value = PropertyUtils.getProperty(this, field.getName());

			List<Map<String, Object>> keyvalues = this.getBeanTable().get(SQLCriterion.get(field.getName(), value));
			if(!keyvalues.isEmpty()){
				KVUtils.toBean(keyvalues.get(0), this);
			}

		} catch (Exception e) {
			log.error("查询记录出现异常", e);
			throw new RuntimeException(e);
		}
	}

}
<p>

在使用的时候只需要继承此对象,增删改查的功能就不用在写,子类可以增加新方法,也可以覆盖夫类的方法。未来的社会的智能的社会,智能的社会需要智能的工具,智能工具需要智能的、功能可独立的软件,这种软件将最终落在智能对象设计上。

cuwkuhaihong
2010-07-04 22:18
一个对象User的增删改查的实现

@BeanTableName(name="z_user")
public class User extends ThinObject {

	@Primary
	String uid ;
	
	String uname;
	String rid;
	
	public User(String userid, String username) {
		super();
		this.uid = userid;
		this.uname = username;
	}
	
	public User() {
	}
	@Override
	public String toString() {
		return "(userid:"+uid+", username:"+uname+")";
	}

	public String getUid() {
		return uid;
	}

	public void setUid(String uid) {
		this.uid = uid;
	}

	public String getUname() {
		return uname;
	}

	public void setUname(String uname) {
		this.uname = uname;
	}

	public String getRid() {
		return rid;
	}
	public void setRid(String rid) {
		this.rid = rid;
	}
}
<p>

测试类:

public class TestUser extends TestCase {

	static {
		new TryThinContext("zero");
		ThinContext.setDefaultSchema("zero");
	}
	
	public void testUpdate() throws SQLException{
		User user = new User("wanghh","洪");
		user.obtainMe();
		user.setUname("测试");
		user.updateMemory("uname");
		System.out.println(user.rid);
		
	}
	
	public void testAdd() throws SQLException{
		User user = new User("thinery","洪");
		user.setRid("admin");
		user.remember();
	}
	
	public void testDelete() throws SQLException{
		User user = new User();
		user.setUid("thinery");
		user.forget();
	}
	
	public void testQuery() throws SQLException{
		User user = new User();
		List<Object> users = user.associate(SQLCriterion.get("rid", Operator.EQ, "marketing"));
		System.out.println(users);
		
	}
	
	@Override
	protected void tearDown() throws Exception {
		ThinContext.ctx.cleanHoldConection();
	}
}
<p>

[该贴被cuwkuhaihong于2010-07-04 22:19修改过]

[该贴被cuwkuhaihong于2010-07-04 22:20修改过]

oojdon
2010-07-05 12:53
很有想法的楼主,不错,加油。

我正在研究你的代码,呵呵!

banq
2010-07-05 19:03
2010年07月04日 19:57 "cuwkuhaihong"的内容
这种对象与对象之间相同与否的问题,是只有具备智能的动物或者智能机器人才有的能力做这样的结论,大多数的对象是没有此能力的 ...

我认可这个观点,我们在建立Object,要注意它是一个智能,能够知道什么,决定做什么,自己做决定,职责驱动开发中讲得比较多。

这应该是一种主流的对象建模方法。

猜你喜欢
3Go 1 2 3 下一页