软件开发中的项目的架构的终极目标就六个字:
高内聚、低耦合。
架构搭建好了,后期可维护性才干提高,在这基础上,假设还想提高项目的高效性,就仅仅能从算法着手
假设项目中算法都已经做到极致了,还想提高项目的高效性,怎么办?(算法并不一定能处理高并发的问题)
就要用到中间件的技术了
以下我就从这三方面来搭建一个项目
假设我们有个这么需求 我公式和YC公式合作,开发一个项目。这个项目功能是用来測量东西的一个项目,我们公式在存储数据方面做得好,YC公司所以要和我们合作。要我们做一个对数据进行保存的容器,他们公司直接用我公司的容器来保存測量的数据;
对于我公司来说,我们仅仅要管好数据保存方面就好了。对于怎么測量,我们管不着,由于測量的范围和方式太广了,我们公司是做通用平台的,所以我公司仅仅要提供一个測量接口即可了。详细怎么实现,由买我公司项目的YC公司去详细实现。
以下来看详细案例
首先是我公司的容器类,用来保存測量数据的
package com.my;
/***
* 容器类,用来存測量数据的。而且能够对数据进行一系列的操作
*
* @author 汤高
*
*/
public class Container {
private Object maxobj;// 最大的測量对象
private Object minobj;// 最小的測量对象
private double sum;// 測量数据的和
private double avg;// 平均值
private Measuraable measuraable;// 測量工具
//private Filter filter;
private Object[] objects;// 用来存放数据的集合
private int size;// 数组的实际容量
public static final int NUM = 10;// 数组的初始化容量
/**
* 构造函数初始化各属性值
*/
public Container() {
this.maxobj = null;
this.minobj = null;
this.sum = 0;
this.avg = 0;
this.measuraable = null;
this.size = 0;
objects = new Object[NUM];
}
public double getAvg() {
return avg;
}
public Object getMaxobj() {
return maxobj;
}
public Object getMinobj() {
return minobj;
}
public int getSize() {
return size;
}
//设置測量容器
public void setMeasuraable(Measuraable measuraable) {
this.measuraable = measuraable;
}
public void add(Object obj) throws Exception {
// 优雅的设计 第一步 容错处理
if (obj == null) {
throw new RuntimeException("要測量的对象不能为空。您传入的对象为:" + obj);// 非受检异常
}
if (this.measuraable == null) {
throw new Exception(" 測量工具不能为空");// 受检异常 要么抛出 要么捕获
}
double value = this.measuraable.Measure(obj);
if (size == 0) { // 刚開始測第一个对象 把最大值最小值都付给第一个对象
maxobj = obj;
minobj = obj;
} else {
double maxvalue = this.measuraable.Measure(maxobj);
double minvalue = this.measuraable.Measure(minobj);
if (value > maxvalue) {
maxobj = obj;
}
if (value < minvalue) {
minobj = obj;
}
}
// 拓容处理
enlargeArray();
objects[size] = obj;// 把測量对象存入数组
size++;// 实际大小加1
sum += sum;// 求和
avg = sum / size;// 计算平均值
}
public void enlargeArray() {
int oldLength = objects.length;
if (size > objects.length) {
// 创建新数组 ,长度为原数组的两倍
Object[] newobjects = new Object[objects.length * 2];
// 将原数组的数据存到新数组中
System.arraycopy(objects, 0, newobjects, 0, size);
// 将newobjects的地址赋值给 objects
objects = newobjects;
System.gc();// gc()垃圾回收. 高级->重写虚拟机
}
}
/**
* 返回全部的測量过的数据 objects默认10个数据。可是不一定存满,仅仅能返回有效数据
* @return
*/
public Object[] getAllData(){
Object[] newobject = new Object[size];
System.arraycopy(objects, 0, newobject, 0, size);
return newobject;
}
//public void setFilter(Filter filter) {
// this.filter=filter;
//}
}
上面就是我公司的核心功能了,就是用来保存数据
对于如何測,我公司仅仅提供一个接口
package com.my;
/***
* 測量工具的接口
* @author 汤高
*
*/
public interface Measuraable {
/***
* 測量的方法,提供模板,详细怎么实现 我无论,交给要測量的公司来详细实现
* @param obj 測量对象
* @return 返回一个对象的測量结果
*/
public double Measure(Object obj);
}
详细怎么測试,怎么去实现。由买我们公司的YC去实现
YC公司是用来測BMI值的(人的健康指数)
package com.yc;
import javax.management.RuntimeErrorException;
import com.my.Measuraable;
public class Bmi implements Measuraable {
@Override //bmi=weight/(height*height)
public double Measure(Object object) {
if(object==null){
throw new RuntimeException("要測量的对象不能为空");
}
if( !(object instanceof Person ) ){
throw new RuntimeException("要測量的对象必须是一个Person");
}
//将Object 强制类型转换为Person 以取出 height,weight
Person p=(Person)object;
double height=p.getHeight();
double weight=p.getWeight();
return weight/(height*height);
}
}
好了。YC公司已经自己做了測量的实现,所以,我们两公司的合作就临时告一段落了
看測试类。
package test1;
import org.junit.Test;
import com.my.Container;
import com.my.Filter;
import com.yc.Bmi;
import com.yc.BmiDataFilter;
import com.yc.Person;
public class TestVersion1 {
@Test
public void test() throws Exception {
Bmi bmi = new Bmi();
Filter filter = new BmiDataFilter();
Container c = new Container();
c.setMeasuraable(bmi);// 將bmi载入到 container容器
// c.setFilter(filter);
Person p1 = new Person("张三", 70, 2.23);// bmi 最小
Person p2 = new Person("李四", 250, 1.3);// bmi 最大
Person p3 = new Person("王五", 100, 1.9);
Person p4 = new Person("赵六", 500, 2);// 不合理
Person p5 = new Person("田七", 200, 1.7);
// 存
c.add(p1);
c.add(p2);
c.add(p3);
try {
c.add(p4);
} catch (Exception e) {
e.printStackTrace();
}
c.add(p5);
// 取出最大值
Object max = c.getMaxobj();
Person maxPerson = (Person) max;
// 取出最小值
Object min = c.getMinobj();
Person minPerson = (Person) min;
System.out.println("最大值" + maxPerson);
System.out.println("最小值" + minPerson);
// 取出全部的值
System.out.println("==========全部的值============");
Object[] objs = c.getAllData();
for (Object o : objs) {
Person p = (Person) o;
System.out.println(p);
}
}
}
大家看看结果:
最大值Person [name=李四, weight=250.0, height=1.3]
最小值Person [name=张三, weight=70.0, height=2.23]
==========全部的值============
Person [name=张三, weight=70.0, height=2.23]
Person [name=李四, weight=250.0, height=1.3]
Person [name=王五, weight=100.0, height=1.9]
Person [name=赵六, weight=500.0, height=2.0]
Person [name=田七, weight=200.0, height=1.7]
居然有重量为500斤的,明显不合要求啊!
数据不合理啊,所以YC公司就来找我们公司麻烦,要求我们公司把这个问题解决,必需要我们队数据进行过滤。我们公司老板就不干了 啊,我们是管数据储存的。你居然还要我们管过滤,那不行。我公司是做通用平台的。做不了详细的过滤实现。你们公司是測人,可是假如别的公司測猪的重量了!重量肯定是越种越好啊,所以,我们仅仅做过滤数据的接口,详细怎么实现。你们自己去实现,由于我们仅仅做平台。
所以我们公司提供了过滤接口
package com.my;
//过滤数据的接口
public interface Filter {
public boolean filter(Object object);
}
YC公司听了我们公司老板的话后,认为是他们不正确。详细实现数据过滤应该他们自己做
package com.yc;
import com.my.Filter;
public class BmiDataFilter implements Filter {
@Override
public boolean filter(Object object) {
if (object == null) {
throw new RuntimeException("要过滤的对象不能为空");
}
if (!(object instanceof Person)) {
throw new RuntimeException("要过滤的对象必须是一个Person");
}
// 将Object 强制类型转换为Person 以取出 height,weight
Person p = (Person) object;
double height = p.getHeight();
double weight = p.getWeight();
if(height<1||height>2.5){
//throw new RuntimeException("身高数据不合理"+height);
return false;
}
if(weight<40||weight>400){
return false;
}
return true;
}
}
好了。过滤数据的功能做好了,以下再看看測试。
首先先在容器类里面加入一个过滤器
package com.my;
/***
* 容器类。用来存測量数据的,而且能够对数据进行一系列的操作
*
* @author 汤高
*
*/
public class Container {
private Object maxobj;// 最大的測量对象
private Object minobj;// 最小的測量对象
private double sum;// 測量数据的和
private double avg;// 平均值
private Measuraable measuraable;// 測量工具
private Filter filter;
private Object[] objects;// 用来存放数据的集合
private int size;// 数组的实际容量
public static final int NUM = 10;// 数组的初始化容量
/**
* 构造函数初始化各属性值
*/
public Container() {
this.maxobj = null;
this.minobj = null;
this.sum = 0;
this.avg = 0;
this.measuraable = null;
this.size = 0;
objects = new Object[NUM];
}
// 加入对数据过滤的过滤器
public void setFilter(Filter filter) {
this.filter = filter;
}
public double getAvg() {
return avg;
}
public Object getMaxobj() {
return maxobj;
}
public Object getMinobj() {
return minobj;
}
public int getSize() {
return size;
}
// 设置測量容器
public void setMeasuraable(Measuraable measuraable) {
this.measuraable = measuraable;
}
public void add(Object obj) throws Exception {
// 优雅的设计 第一步 容错处理
if (obj == null) {
throw new RuntimeException("要測量的对象不能为空,您传入的对象为:" + obj);// 非受检异常
}
if (this.measuraable == null) {
throw new Exception(" 測量工具不能为空");// 受检异常 要么抛出 要么捕获
}
// 推断是否有过滤器。假设有,则调用过滤器的过滤功能进行过滤
if (this.filter != null) {
if (this.filter.filter(obj) == false) {
throw new RuntimeException("要过滤的对象不是有效对象,数据错误。请检查" + obj);
}
}
double value = this.measuraable.Measure(obj);
if (size == 0) { // 刚開始測第一个对象 把最大值最小值都付给第一个对象
maxobj = obj;
minobj = obj;
} else {
double maxvalue = this.measuraable.Measure(maxobj);
double minvalue = this.measuraable.Measure(minobj);
if (value > maxvalue) {
maxobj = obj;
}
if (value < minvalue) {
minobj = obj;
}
}
// 拓容处理
enlargeArray();
objects[size] = obj;// 把測量对象存入数组
size++;// 实际大小加1
sum += sum;// 求和
avg = sum / size;// 计算平均值
}
public void enlargeArray() {
int oldLength = objects.length;
if (size > objects.length) {
// 创建新数组 ,长度为原数组的两倍
Object[] newobjects = new Object[objects.length * 2];
// 将原数组的数据存到新数组中
System.arraycopy(objects, 0, newobjects, 0, size);
// 将newobjects的地址赋值给 objects
objects = newobjects;
System.gc();// gc()垃圾回收. 高级->重写虚拟机
}
}
/**
* 返回全部的測量过的数据 objects默认10个数据。可是不一定存满,仅仅能返回有效数据
*
* @return
*/
public Object[] getAllData() {
Object[] newobject = new Object[size];
System.arraycopy(objects, 0, newobject, 0, size);
return newobject;
}
}
以下再測试
package test1;
import org.junit.Test;
import com.my.Container;
import com.my.Filter;
import com.yc.Bmi;
import com.yc.BmiDataFilter;
import com.yc.Person;
public class TestVersion1 {
@Test
public void test() throws Exception {
Bmi bmi = new Bmi();
Filter filter = new BmiDataFilter();
Container c = new Container();
c.setMeasuraable(bmi);// 將bmi载入到 container容器
c.setFilter(filter);
Person p1 = new Person("张三", 70, 2.23);// bmi 最小
Person p2 = new Person("李四", 250, 1.3);// bmi 最大
Person p3 = new Person("王五", 100, 1.9);
Person p4 = new Person("赵六", 500, 2);// 不合理
Person p5 = new Person("田七", 200, 1.7);
// 存
c.add(p1);
c.add(p2);
c.add(p3);
try {
c.add(p4);
} catch (Exception e) {
e.printStackTrace();
}
c.add(p5);
// 取出最大值
Object max = c.getMaxobj();
Person maxPerson = (Person) max;
// 取出最小值
Object min = c.getMinobj();
Person minPerson = (Person) min;
System.out.println("最大值" + maxPerson);
System.out.println("最小值" + minPerson);
// 取出全部的值
System.out.println("==========全部的值============");
Object[] objs = c.getAllData();
for (Object o : objs) {
Person p = (Person) o;
System.out.println(p);
}
}
}
大家看看结果
java.lang.RuntimeException: 要过滤的对象不是有效对象,数据错误,请检查Person [name=赵六, weight=500.0, height=2.0]
at com.my.Container.add(Container.java:78)
at test1.TestVersion1.test(TestVersion1.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod1.runReflectiveCall(FrameworkMethod.java:50)atorg.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)atorg.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)atorg.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)atorg.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)atorg.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)atorg.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)atorg.junit.runners.ParentRunner3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner1.schedule(ParentRunner.java:71)atorg.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)atorg.junit.runners.ParentRunner.access000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
最大值Person [name=李四, weight=250.0, height=1.3]
最小值Person [name=张三, weight=70.0, height=2.23]
==========全部的值============
Person [name=张三, weight=70.0, height=2.23]
Person [name=李四, weight=250.0, height=1.3]
Person [name=王五, weight=100.0, height=1.9]
Person [name=田七, weight=200.0, height=1.7]
数据为500的就被过滤掉了
从上面这个案例就能够看出。做项目架构的重要性了,真正实现了高内聚、低耦合。大家能够细致去体会体会,欢迎大家提出问题,大家一起进步!
后面我还会更新 如何用算法来提高项目的效率。