OOAD
什么是
OOAD?
面向對象的分析與設計
,
使用面向對象的思想對一個系統的分析與設計
UML:
什么是
UML?
統一的建模語言
,
什么是建模
?
將客觀事物圖形化
,
比如蓋樓房
,
首先要把地基打好
統一指的是什么
?
在計算機領域有很多的圖形語言
,
這樣就需要一個標准
,UML
就是這樣的一個標准
,
建模就是將需求用圖的方式表達出來
UML
的組成
:
1.
元素
:
角色
,
用例
2.
圖形
3.
擴展機制
:
擴展基本元素功能的機制
圖形分類
:
靜態圖
,
動態圖
靜態圖
:
類圖
(
描述類與類之間關系的圖
),
對象圖
,
部署圖
(
拓撲結構
),
組件圖
,
用例圖
(
從客戶的角度來描述系統的整個功能
)
動態圖
:
協作圖
(
按空間的交互圖
),
序列圖
(
時序圖
,
描述多個對象按時間的交互過程
),
活動圖
(
描述業務流程
,
也能做一個操作的建模
),
狀態圖
(
描述單個的對象
,
或者是單個的子系統的狀態變化
)
類圖
:
類圖
,
描述類與類之間關系的圖
例子
:
圖書管理系統
1.
利用
OO
的思想找對象
:
如
:
圖書管理員
,
借書人
,
庫存管理人員
,
書籍等等
2.
把他們抽象出來
:
找到與業務有關系的對象和對象的屬性
3.
形成類
,
畫出類圖來
4.
實例並建立實例間的通訊
類之間的關系
:
1.
繼承
2.
實現
3.
關聯
4.
依賴
5.
聚合
6.
組合
什么是關聯
?
類的屬性使用的是另一個類的引用或者是對象
什么是依賴
?
除了屬性
,
其他地方使用了另一個類的對象
,
引用
,
屬性
,
方法就叫
A
類依賴
B
類
/**
*
知識點
:
*
關聯
*
程序目標
:
* java
文件說明
:
* A.java
* B.java
* Test.java:
*
讓
A
和
B
關聯起來
,
讓
A
類調用
B
類的方法
,
讓
B
類使用
A
類的方法
*/
package MY.module01.leitu.guanlian;
public class Test {
public static void test(){
A a=new A();
B b=new B();
a.setB(b);
b.setA(a);
a.getB().bf();
b.getA().af();
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Test.test();
}
}
package MY.module01.leitu.guanlian;
public class A {
private B b;
public A() {
super();
// TODO Auto-generated constructor stub
}
public A(B b) {
super();
// TODO Auto-generated constructor stub
this.b = b;
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
public void af(){
System.out.println("A's af()");
}
}
package MY.module01.leitu.guanlian;
public class B {
private A a;
public B() {
super();
// TODO Auto-generated constructor stub
}
public B(A a) {
super();
// TODO Auto-generated constructor stub
this.a = a;
}
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
public void bf(){
System.out.println("B's bf()");
}
}
/**
*
知識點
:
*
依賴的三種情況
*
程序目標
:
* java
文件
:
* A.java
* B.java
*
一個類的方法去使用另一個類的元素
*/
package MY.module01.leitu.yilai;
public class A {
public void a1(B b){
int rst=b.add(1,2);
System.out.println(rst);
}
public void a2(){
B b=new B();
int rst=b.add(1,2);
System.out.println(rst);
}
public void a3(){
int rst=B.add2(10,20);
System.out.println(rst);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
A a=new A();
a.a1(new B());
a.a2();
a.a3();
}
}
package MY.module01.leitu.yilai;
public class B {
public int add(int i,int j){
return i+j;
}
public static int add2(int i,int j){
return i+j;
}
}
什么是聚合
?
比如說同學聚會
,
有很多的同學聚集在一起
,
但是
,
缺少幾個也沒有什么關系
什么是組合
?
比如說人
,
有心臟
,
肝
,
肺
,
組成為一個人
,
如果少了其中的一部分
,
就會死掉
,
誰也離不開誰
靜態圖
:
用例圖
從客戶的角度來描述系統的整個過程
組成
:
角色
,
用例
,
關聯
角色之間的關系
:
繼承關系
,
依賴關系
例如
:
客戶是一個角色
,
客戶分為大客戶
,
小客戶
,
這是繼承關系
借書人和圖書管理員就是依賴關系
用例的關系
:
包含
,
擴展關系
例如
:
借書功能
:
登陸
,
查詢等
,
這個是包含
靜態圖
:
部署圖
整個系統的軟硬件拓撲結構
如
:CPU,eclipes
等
靜態圖
:
組件圖
表示物理的實現
,
實現指的是代碼
,
這個用的少
動態圖
:
序列圖
按時間的先后順序描述對象之間的交互
/**
*
知識點
:
*
模擬序列圖的執行
*
程序目標
:
* java
文件
:
* Client.java:
調用
MainController
類的方法
* MainController.java:
這個方法中調用了
Service
類的方法
* Service.java:
這個類的方法調用了另一個類的方法
* DAO.java:
這個類的方法調用自身的一個方法
,
這叫反身消息
*/
package MY.module01.leitu.xulietu;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MainController m=new MainController();
m.f();
}
}
package MY.module01.leitu.xulietu;
public class MainController {
public void f(){
Service s=new Service();
s.f();
}
}
package MY.module01.leitu.xulietu;
public class Service {
public void f(){
DAO d=new DAO();
d.genName();
}
}
package MY.module01.leitu.xulietu;
public class DAO {
public void genName(){
System.out.println("hello");
f();
}
private void f(){
System.out.println("dao's shi fan shen");
}
}
動態圖
:
活動圖
可以有分之的判斷
動態圖
:
狀態圖
可以看到對象的狀態變化
設計模式
:
為什么要設計
?
1.
軟件的復用
2.
軟件的維護
開閉原則
:
對高層的修改關閉
,
對低層的擴展開放
模板方法
:
它實現了開閉原則
/**
*
知識點
:
*
開
-
閉原則
:
模板方法
*
程序目標
:
* java
文件
:
* CET6.java:
高層的邏輯
,
只開發了給低層用的方法
,
聽
,
說
* ConcretCET6.java:
這里來實現聽
,
說
* TestCET6.java
*/
package MY.module01.sjms.kbyz;
public class TestCET6 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
CET6 c=new ConcretCET6();
c.passCET6();
}
}
package MY.module01.sjms.kbyz;
public abstract class CET6 {
//
高層業務邏輯
public final void passCET6(){
listen();
say();
}
//
提供給低層實現的業務
abstract protected void listen();
abstract protected void say();
}
package MY.module01.sjms.kbyz;
public class ConcretCET6 extends CET6{
@Override
protected void listen() {
// TODO Auto-generated method stub
System.out.println("listen");
}
@Override
protected void say() {
// TODO Auto-generated method stub
System.out.println("say");
}
}
里氏代換原則
:
任何父類適用的地方
,
子類一定適用
,
子類可以當父類用
策略模式
:
實現了里氏代換原則
,
解決了可選算法的問題
什么是策略模式
?
針對共同的問題
,
提供解決方案或指導原則或好壞結果
/**
*
知識點
:
*
里氏代換原則
:
策略模式
*
程序目標
:
*
打折的例子
,
涉及到可選算法的問題
* java
文件
:
* Context.java:
打折的方法和設置折扣的方法
,
和
DisCount
為關聯關系
*
這里體現了里氏代換原則
,
子類當父類用
* DisCount.java:
打折算法抽象類
* dis1.java:
打折算法
1
* dis2.java:
打折算法
2
* Client.java:1.
設置折扣率
,2.
打折
*/
package MY.module01.sjms.celuemoshi;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Context c=new Context();//
算法選擇器
// c.setD(new dis2());
c.setD(new dis1());//
選擇折扣
c.getprice(100);//
打折
}
}
package MY.module01.sjms.celuemoshi;
public class Context {
private DisCount d;
public void setD(DisCount d) {
this.d = d;
}
public void getprice(double price){
System.out.println(d.discout(price));
}
}
package MY.module01.sjms.celuemoshi;
public class dis1 extends DisCount{
@Override
public double discout(double price) {
// TODO Auto-generated method stub
return price*0.8;
}
}
package MY.module01.sjms.celuemoshi;
public class dis2 extends DisCount{
@Override
public double discout(double price) {
// TODO Auto-generated method stub
return price;
}
}
package MY.module01.sjms.celuemoshi;
public abstract class DisCount {
public abstract double discout(double price);
}
依賴倒轉原則
:
什么是依賴倒轉原則
?
要依賴抽象
,
不要依賴具體實現
這句話是什么意思呢
?
抽象指的是什么
?
具體實現指的又是什么
?
誰要依賴抽象
?
一個程序要按照高層的設計思路來實現具體的程序功能
,
抽象就是高層
,
具體實現就是為了完成高層的一個目標而寫的程序代碼
,
高層就是戰略
,
低層是戰術
,
高層是整體目標
,
低層是目標的實現
,
高層是思想
,
低層是行為
什么是倒轉
?
這個名字的含義是什么
?
以往的過程式編程注重的是具體的功能實現方法
,
也就是低層
,
它決定了高層
,
這樣是不合理的
,
所以要將這個錯誤的方式扭轉過來
,
取名叫依賴倒轉原則
三種依賴
(
耦合
)
關系的種類
:
零耦合
:
不可能
具體耦合
:
具體的類和類之間的聯系
抽象耦合
:
高層抽象類與類之間的聯系
如何實現依賴倒轉原則呢
?
三種模式
:
第一
,
工廠方法模式
第二
,
模板方法模式
第三
,
迭代子模式
接口隔離原則
:
使用多個專門的接口要比使用一個總的接口要好
比如
:
人類
(
接口
)
學生
(
具體類
)
老師
(
具體類
)
學生老師類
(
具體類
):
這個類要想擁有學生和老師的方法就很麻煩了
,
所以
,
需要再添加兩個接口
,
學生接口和老師接口
組合聚合復用原則
:CARP
將其他對象的功能融合到新的對象里
,
如果其中一個對象死掉了
,
另一個對象也不能用了
,
那么這種情況叫組合
,
反之
,
叫聚合
/**
*
知識點
:
*
依賴關系
,
組合聚合復用
,
里氏代換原則結合
這是聚合
*
程序目標
:
*
例子
:
人學習技能
* People.java:
人
具體類
* Actor.java:
技能類
接口
* Student.java:
技能類
具體類
學習方法
* Teacher.java:
技能類
具體類
教書方法
* Test.java:
讓人具備學習和教書的方法
,
並使用這些能力
*/
package MY.module01.sjms.CARP.t1;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Actor a=new Student();
Actor b=new Teacher();
People p=new People();
p.studyJineng(a);
p.studyJineng(b);
p.useJineng();
}
}
package MY.module01.sjms.CARP.t1;
public interface Actor {
void jineng();
}
package MY.module01.sjms.CARP.t1;
public class Teacher implements Actor{
public void jineng() {
// TODO Auto-generated method stub
System.out.println("theach....");
}
}
package MY.module01.sjms.CARP.t1;
public class Student implements Actor{
public void jineng() {
// TODO Auto-generated method stub
System.out.println("study..");
}
}
package MY.module01.sjms.CARP.t1;
import java.util.ArrayList;
import java.util.List;
public class People {
private String name;
private int age;
private List<Actor>list;
public People(){
list=new ArrayList<Actor>();
}
public void studyJineng(Actor a){
list.add(a);
}
public void useJineng(){
for(Actor a:list){
a.jineng();
}
}
}
迪米特法則
(LoD):
最少知識原則
:
1.
盡量減少耦合
:
類與類之間的訪問減少
,
利用的資源少些
2.
對遠程對象的訪問最好用粗粒度接口來實現
3.
不要和陌生人說話
,
只和直接認識的人聯系就好了
什么是遠程對象
?
什么是粗粒度接口
?
這個遠程對象系統外的對象
,
如果有一個朋友圈和一些陌生人
,
陌生人就屬於系統外的對象
,
就是遠程對象
,
其中有一個人是這個朋友圈的同時也認識這些陌生人
,
那么如果朋友圈中的其他人想與陌生人聯系
,
需要通過他來實現
,
這個他就是門面對象
,
這個對象需要通過一個接口來實現
,
而且這個接口設計的要和這個對象合適
/*
*
知識點
:
*
迪米特法則
(
最少知識原則
):
門面模式
*
程序目標
:
* Computer.java:
看成遠程對象
* Lamp.java:
看成遠程對象
* Office.java:
看成遠程對象
* People.java:
人
,
看成朋友圈
* WorkOffFacade.java:
門面對象
*/
package MY.module01.sjms.Lod.t1;
public class People {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
WorkOffFacade w=new WorkOffFacade();
w.closeWorkOff();
}
}
package MY.module01.sjms.Lod.t1;
//
門面對象
public class WorkOffFacade {
public void closeWorkOff(){
new Computer().closeComputer();
new Lamp().closeLamp();
new Office().closeOther();
}
}
package MY.module01.sjms.Lod.t1;
public class Computer {
public void closeComputer(){
System.out.println("closeComputer");
}
}
package MY.module01.sjms.Lod.t1;
public class Lamp {
public void closeLamp(){
System.out.println("closeLamp");
}
}
package MY.module01.sjms.Lod.t1;
//
相當於遠程對象
public class Office {
public void closeOther(){
System.out.println("closeOther");
}
}