对于AF、RI以及Rep exposure的心得体会(复习笔记一)

对于AF、RI以及Rep exposure的心得体会(复习笔记一)
一、A与R
先介绍两个空间:
R: 表示值(rep值)的空间由实际实现实体的值组成。ADT将作为单个对象实现,但更常见的是需要一个小的对象网络,因此其值通常相当复杂。

A: 抽象值的空间由类型设计为支持的值组成。它们是柏拉图式的实体,不存在如前所述,但它们是我们希望将抽象类型的元素视为该类型的客户机的方式。

对于这两个空间,通俗易懂一点的讲,R为开发者所使用的空间,而A是客户所看到的空间。分别对应了代码端以及实际对象。

引入一个规约进行举例:

 In a Store, there are some kinds of items to sell. Each item has a price.
 * 
 * However, there are some special offers, and a special offer consists of one
 * or more different kinds of items with a sale price.
 * 
 * You are given the each item's price, a set of special offers, and the number
 * we need to buy for each item. The job is to output the lowest price you have
 * to pay for exactly certain items as given, where you could make optimal use
 * of the special offers.
 * 
 * Each special offer is represented in the form of an array, the last number
 * represents the price you need to pay for this special offer, other numbers
 * represents how many specific items you could get if you buy this offer.
 * 
 * You could use any of special offers as many times as you want.
 * 
 * Example 1:
 * 
 * Input: [2,5], [[3,0,5],[1,2,10]], [3,2] Output: 14
 * 
 * Explanation:
 * 
 * There are two kinds of items, A and B. Their prices are $2 and $5
 * respectively.
 * 
 * In special offer 1, you can pay $5 for 3A and 0B
 * 
 * In special offer 2, you can pay $10 for 1A and 2B.
 * 
 * You need to buy 3A and 2B, so you may pay $10 for 1A and 2B (special offer
 * #2), and $4 for 2A.
 * 
 * Example 2:
 * 
 * Input: [2,3,4], [[1,1,0,4],[2,2,1,9]], [1,2,1] Output: 11
 * 
 * Explanation:
 * 
 * The price of A is $2, and $3 for B, $4 for C.
 * 
 * You may pay $4 for 1A and 1B, and $9 for 2A ,2B and 1C.
 * 
 * You need to buy 1A ,2B and 1C, so you may pay $4 for 1A and 1B (special offer
 * #1), and $3 for 1B, $4 for 1C.
 * 
 * You cannot add more items, though only $9 for 2A ,2B and 1C.
 * 
 * 
 * Note:
 * 
 * 1. There are at most 6 kinds of items, 100 special offers.
 * 
 * 2. For each item, you need to buy at most 6 of them.
 * 
 * 3. You are not allowed to buy more items than you want, even if that would
 * lower the overall price.

在这其中,显而易见的是用户所能看到的空间。也就是实体对象:购买商品的个数,购买商品的种类,以及购买商品的特惠套餐,以及顾客的需求数目等等。这也是我们的A空间。
而这个空间是程序员所不能写入代码的空间,因此就需要一个R空间与它进行映射,从而形成了我们的代码,也就是我们的数据结构,也就是R空间。
如下面代码所示,函数传入的三个参数就分别对应了我们想要看到的三种A空间元素:商品种类价格,商品特惠套餐以及用户所需数目。

public class LowestPrice {

	public int shoppingOffers(List<Integer> price, List<List<Integer>> special, List<Integer> needs) {
		return shopping(price, special, needs);
	}

	public int shopping(List<Integer> price, List<List<Integer>> special, List<Integer> needs) {
		try {
			if(price.size() > 6) {
				throw new RIException("输入的price多于6种,不符合要求");
			}
			if(special.size() > 100) {
				throw new RIException("输入special多余100种,不符合要求");
			}
			if(needs.size()!=price.size()) {
				throw new RIException("输入的price与nends关系不符合输入要求,种类数目不一样");
			}
		}catch(RIException ex) {
			ex.printStackTrace(System.out);
			return -1;
		}
		int j = 0, res = dot(needs, price);
		if(res == 0) {
			return 0;
		}
		for (List<Integer> s : special) {
			List<Integer> clone = new ArrayList<>(needs);
			for (j = 0; j < needs.size(); j++) {
				int diff = clone.get(j) - s.get(j);
				if (diff < 0)
					break;
				clone.set(j, diff);
			}
			if (j == needs.size())
				res = Math.min(res, s.get(j) + shopping(price, special, clone));
		}
		return res;
	}

	public int dot(List<Integer> a, List<Integer> b) {
		int sum = 0;
		for (int i = 0; i < a.size(); i++) {
			sum += a.get(i) * b.get(i);
		}
		return sum;
	}
}

二、AF
AF又叫抽象函数。
抽象函数:R和A之间映射关系的函数,即如何去解释R中的每一个值为A中的每一个值。
AF : R → A
AF:满射、非单射、未必双射→R中的部分值并非合法的,在A中无映射值。
先不谈AF的映射合法性,从上面的例子来看,AF也就是从List price, List<List> special, List needs向商品种类价格,商品特惠套餐以及用户所需数目的一组一一映射。
从而撰写AF:

		/**
		 * Abstraction function:
		 * price:商品各个种类及其价格,其中种类是key,而价格是value
		 * special:商品的各种优惠套餐,每个数组的前n(n为商品种类)个
		 * 			为商品个数,第n+1个为套餐价格
		 * needs:分别为每种商品的客户所需数目
		 */

三、RI
RI:将rep值映射到布尔值的rep不变量
RI : R → boolean
对于代表值r,RI(r)是真的,如果且仅当r由AF映射
换句话说,RI告诉我们给定的rep值是否格式良好;或者,可以将RI看作一个集合:它是定义AF的rep值的子集。

总的来说,可以把RI看成一个描述合法化的不变量,即描述AF中所合法的东西。回归上面所说的A空间,RI就是去除了A空间中的不合法化的对象,并让程序员有所实现。
因此,我们根据规约中对于合法性要求的一部分,对于RI进行撰写,首先看规约中对于合法性的要求:

/** 
* Note:
 * 
 * 1. There are at most 6 kinds of items, 100 special offers.
 * 
 * 2. For each item, you need to buy at most 6 of them.
 * 
 * 3. You are not allowed to buy more items than you want, even if that would
 * lower the overall price.
 * /

因此我们得知了对于传入参数List price, List<List> special, List needs的要求,撰写RI:

		/**
		 * Representation invariant:	
		 * price的元素个数多余6个;
		 * special的元素个数少于等于100个
		 * needs中的元素不能大于6
		 */

并在代码中进行相应的实现与检查:

try {
			if(price.size() > 6) {
				throw new RIException("输入的price多于6种,不符合要求");
			}
			if(special.size() > 100) {
				throw new RIException("输入special多余100种,不符合要求");
			}
			if(needs.size()!=price.size()) {
				throw new RIException("输入的price与nends关系不符合输入要求,
										种类数目不一样");
			}
			for(int i = 0;i<needs.size();i++) {
				if(needs.get(i) > 6) {
					throw new RIException("买的商品数目过多");
				}
			}
		}catch(RIException ex) {
			ex.printStackTrace(System.out);
			return -1;
		}

四、Documenting rep exposure safety argument
表示泄漏的安全声明。
这是一个注释,它检查rep的每个部分,查看处理该部分rep的代码(特别是有关参数和来自客户机的返回值的代码,因为这是rep公开发生的地方),并给出代码不公开rep的原因。
给出理由,证明代码并未对外泄露其内部表示——自证清白。

展开阅读全文

Git 实用技巧

11-24
这几年越来越多的开发团队使用了Git,掌握Git的使用已经越来越重要,已经是一个开发者必备的一项技能;但很多人在刚开始学习Git的时候会遇到很多疑问,比如之前使用过SVN的开发者想不通Git提交代码为什么需要先commit然后再去push,而不是一条命令一次性搞定; 更多的开发者对Git已经入门,不过在遇到一些代码冲突、需要恢复Git代码时候就不知所措,这个时候哪些对 Git掌握得比较好的少数人,就像团队中的神一样,在队友遇到 Git 相关的问题的时候用各种流利的操作来帮助队友于水火。 我去年刚加入新团队,发现一些同事对Git的常规操作没太大问题,但对Git的理解还是比较生疏,比如说分支和分支之间的关联关系、合并代码时候的冲突解决、提交代码前未拉取新代码导致冲突问题的处理等,我在协助处理这些问题的时候也记录各种问题的解决办法,希望整理后通过教程帮助到更多对Git操作进阶的开发者。 本期教程学习方法分为“掌握基础——稳步进阶——熟悉协作”三个层次。从掌握基础的 Git的推送和拉取开始,以案例进行演示,分析每一个步骤的操作方式和原理,从理解Git 工具的操作到学会代码存储结构、演示不同场景下Git遇到问题的不同处理方案。循序渐进让同学们掌握Git工具在团队协作中的整体协作流程。 在教程中会通过大量案例进行分析,案例会模拟在工作中遇到的问题,从最基础的代码提交和拉取、代码冲突解决、代码仓库的数据维护、Git服务端搭建等。为了让同学们容易理解,对Git简单易懂,文章中详细记录了详细的操作步骤,提供大量演示截图和解析。在教程的最后部分,会从提升团队整体效率的角度对Git工具进行讲解,包括规范操作、Gitlab的搭建、钩子事件的应用等。 为了让同学们可以利用碎片化时间来灵活学习,在教程文章中大程度降低了上下文的依赖,让大家可以在工作之余进行学习与实战,并同时掌握里面涉及的Git不常见操作的相关知识,理解Git工具在工作遇到的问题解决思路和方法,相信一定会对大家的前端技能进阶大有帮助。
©️2020 CSDN 皮肤主题: 游动-白 设计师: 上身试试 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值