大型專案架構搭建_高內聚、低耦合(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的就被過濾掉了
從上面這個案例就可以看出,做專案架構的重要性了,真正實現了高內聚、低耦合,大家可以仔細去體會體會,歡迎大家提出問題,大家一起進步!
下面是我專案的原始碼,大家可以下載
後面我還會更新 怎樣用演算法來提高專案的效率。
相關文章
- 軟體工程-----高內聚低耦合軟體工程
- 高內聚,低耦合的實現方式
- 精通介面隔離原則,輕鬆實現高內聚、低耦合架構架構
- Java 工程解耦即高內聚低耦合Java解耦
- 分散式系統關注點——「高內聚低耦合」詳解分散式
- 物件導向三大特性五大原則 + 低耦合高內聚物件
- Laravel 的中大型專案架構Laravel架構
- Android專案架構搭建Android架構
- 如何設計一個高內聚低耦合的模組——MegEngine 中自定義 Op 系統的實踐經驗
- [技術討論]OO原則中鬆耦合與高內聚的分析
- 大型分散式網站架構實戰專案分析分散式網站架構
- 架構系列:ASP.NET 專案結構搭建架構ASP.NET
- 大型網站技術架構(五)--網站高可用架構網站架構
- 從零開始的Android新專案(1):架構搭建篇Android架構
- 大型網站架構系列:電商網站架構案例(1)網站架構
- 乾貨 | 大型網站專案架構技術一覽網站架構
- mysql高可用架構MHA搭建MySql架構
- 大型網站技術架構核心原理(1)網站架構
- 高併發架構的搭建(二)架構
- 如何構建「大型 Node.js 專案」的專案結構?Node.js
- Vue 在大型專案中的架構設計和最佳實踐Vue架構
- 如何構建大型的前端專案前端
- 大型網站技術架構(二)--大型網站架構演化網站架構
- 大型網站技術架構(一)--大型網站架構演化網站架構
- 實戰複雜低程式碼專案React從架構到拆解React架構
- 大型網站架構網站架構
- 微服務架構大型電商專案開發流程及技術實戰微服務架構
- 專案重構之架構架構
- flask-restful 大型專案結構示例FlaskREST
- 從零開始搭建架構實施Android專案架構Android
- 大型網站架構系列:負載均衡詳解(1)網站架構負載
- 說說大型高併發高負載網站的系統架構(更新)負載網站架構
- 大型網站架構演化網站架構
- 專案-整體架構架構
- 專案-安全架構架構
- 談談專案架構架構
- Java高階架構專案實戰(含面電子書)Java架構
- 大型網站技術架構(三)--架構模式網站架構模式