软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 架构设计 -> 大型项目架构搭建_高内聚、低耦合(1) -> 正文阅读

[架构设计]大型项目架构搭建_高内聚、低耦合(1)


软件开发中的项目的架构的终极目标就六个字:
高内聚、低耦合;
架构搭建好了,后期可维护性才能提高,在这基础上,如果还想提高项目的高效性,就只能从算法着手
如果项目中算法都已经做到极致了,还想提高项目的高效性,怎么办?(算法并不一定能处理高并发的问题)
就要用到中间件的技术了
下面我就从这三方面来搭建一个项目
假设我们有个这么需求 我公式和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的就被过滤掉了
从上面这个案例就可以看出,做项目架构的重要性了,真正实现了高内聚、低耦合,大家可以仔细去体会体会,欢迎大家提出问题,大家一起进步!
后面我还会更新 怎样用算法来提高项目的效率。
......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-03-29 23:00:06  
架构设计 最新文章
Opengl教程之读取obj并绘制在picturecontro
读《企业应用架构模式》第五章并发
StepbyStepintoSpring(IOC)
设计模式(2)用例图之一
使用实体组件系统(ECS)开发”吃方块”游戏实
编程学习之简单工厂模式与策略模式
Invalidprojectdescription.
基于Redis实现分布式消息队列(2)
《开源框架那点事儿15》:借船下海还是造船
原型模式——浅复制和深复制
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年1日历
2018-1-17 9:26:27
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --