編寫(xiě)軟件過(guò)程中,程序員面臨著來(lái)自 耦合性,內(nèi)聚性以及可維護(hù)性,可擴(kuò)展性,重用性,靈活性等多方面的挑戰(zhàn),設(shè)計(jì)模式是為了讓程序(軟件),具有更好
編寫(xiě)軟件過(guò)程中,程序員面臨著來(lái)自 耦合性,內(nèi)聚性以及可維護(hù)性,可擴(kuò)展性,重用性,靈活性等多方面的挑戰(zhàn),設(shè)計(jì)模式是為了讓程序(軟件),具有更好
設(shè)計(jì)模式原則,其實(shí)就是程序員在編程時(shí),應(yīng)當(dāng)遵守的原則,也是各種設(shè)計(jì)模式的基礎(chǔ)(即:設(shè)計(jì)模式為什么這樣設(shè)計(jì)的依據(jù))
** 設(shè)計(jì)模式常用的七大原則有:**
對(duì)類(lèi)來(lái)說(shuō)的,即一個(gè)類(lèi)應(yīng)該只負(fù)責(zé)一項(xiàng)職責(zé)。如類(lèi) A 負(fù)責(zé)兩個(gè)不同職責(zé):職責(zé) 1,職責(zé)2。當(dāng)職責(zé)1 需求變更而改變 A 時(shí),可能造成職責(zé) 2 執(zhí)行錯(cuò)誤,所以需要將類(lèi) A 的粒度分解為 A1,A2
2.3.2應(yīng)用實(shí)例以交通工具案例`
public class SingleResponsibility1 {public static void main(String[] args) {Vehicle vehicle = new Vehicle();
vehicle.run("摩托車(chē)");
vehicle.run("汽車(chē)");
vehicle.run("飛機(jī)");
}
}
// 交通工具類(lèi)
// 方式 1
// 1. 在方式 1 的 run 方法中,違反了單一職責(zé)原則
// 2. 解決的方案非常的簡(jiǎn)單,根據(jù)交通工具運(yùn)行方法不同,分解成不同類(lèi)即可
class Vehicle {public void run(String vehicle) {System.out.println(vehicle + " 在公路上運(yùn)行....");
}
}
public class SingleResponsibility2 {public static void main(String[] args) {RoadVehicle roadVehicle = new RoadVehicle();
roadVehicle.run("摩托車(chē)");
roadVehicle.run("汽車(chē)");
AirVehicle airVehicle = new AirVehicle();
airVehicle.run("飛機(jī)");
}
}
//方案 2 的分析
//1. 遵守單一職責(zé)原則
//2. 但是這樣做的改動(dòng)很大,即將類(lèi)分解,同時(shí)修改客戶(hù)端
//3. 改進(jìn):直接修改 Vehicle 類(lèi),改動(dòng)的代碼會(huì)比較少=>方案 3
class RoadVehicle {public void run(String vehicle) {System.out.println(vehicle + "公路運(yùn)行");
}
}
class AirVehicle {public void run(String vehicle) {System.out.println(vehicle + "天空運(yùn)行");
}
}
class WaterVehicle {public void run(String vehicle) {System.out.println(vehicle + "水中運(yùn)行");
}
}
package com.atguigu.principle.singleresponsibility;
public class SingleResponsibility3 {public static void main(String[] args) { Vehicle2 vehicle2 = new Vehicle2();
vehicle2.run("汽車(chē)");
vehicle2.runWater("輪船");
vehicle2.runAir("飛機(jī)");
}
}
//方式3的分析
//1. 這種修改方法沒(méi)有對(duì)原來(lái)的類(lèi)做大的修改,只是增加方法
//2. 這里雖然沒(méi)有在類(lèi)這個(gè)級(jí)別上遵守單一職責(zé)原則,但是在方法級(jí)別上,仍然是遵守單一職責(zé)
class Vehicle2 {public void run(String vehicle) {//處理
System.out.println(vehicle + " 在公路上運(yùn)行....");
}
public void runAir(String vehicle) {System.out.println(vehicle + " 在天空上運(yùn)行....");
}
public void runWater(String vehicle) {System.out.println(vehicle + " 在水中行....");
}
//方法2.
//..
//..
//...
}
2.3.3單一職責(zé)原則注意事項(xiàng)和細(xì)節(jié)public class Segregation1 {public static void main(String[] args) {// TODO Auto-generated method stub
}
}
//接口
interface Interface1 {void operation1();
void operation2();
void operation3();
void operation4();
void operation5();
}
class B implements Interface1 {public void operation1() {System.out.println("B 實(shí)現(xiàn)了 operation1");
}
public void operation2() {System.out.println("B 實(shí)現(xiàn)了 operation2");
}
public void operation3() {System.out.println("B 實(shí)現(xiàn)了 operation3");
}
public void operation4() {System.out.println("B 實(shí)現(xiàn)了 operation4");
}
public void operation5() {System.out.println("B 實(shí)現(xiàn)了 operation5");
}
}
class D implements Interface1 {public void operation1() {System.out.println("D 實(shí)現(xiàn)了 operation1");
}
public void operation2() {System.out.println("D 實(shí)現(xiàn)了 operation2");
}
public void operation3() {System.out.println("D 實(shí)現(xiàn)了 operation3");
}
public void operation4() {System.out.println("D 實(shí)現(xiàn)了 operation4");
}
public void operation5() {System.out.println("D 實(shí)現(xiàn)了 operation5");
}
}
class A {//A 類(lèi)通過(guò)接口Interface1 依賴(lài)(使用) B類(lèi),但是只會(huì)用到1,2,3方法
public void depend1(Interface1 i) {i.operation1();
}
public void depend2(Interface1 i) {i.operation2();
}
public void depend3(Interface1 i) {i.operation3();
}
}
class C {//C 類(lèi)通過(guò)接口Interface1 依賴(lài)(使用) D類(lèi),但是只會(huì)用到1,4,5方法
public void depend1(Interface1 i) {i.operation1();
}
public void depend4(Interface1 i) {i.operation4();
}
public void depend5(Interface1 i) {i.operation5();
}
}
2.4.3應(yīng)傳統(tǒng)方法的問(wèn)題和使用接口隔離原則改進(jìn)package com.atguigu.principle.segregation.improve;
public class Segregation1 {public static void main(String[] args) {// TODO Auto-generated method stub
// 使用一把
A a = new A();
a.depend1(new B()); // A類(lèi)通過(guò)接口去依賴(lài)B類(lèi)
a.depend2(new B());
a.depend3(new B());
C c = new C();
c.depend1(new D()); // C類(lèi)通過(guò)接口去依賴(lài)(使用)D類(lèi)
c.depend4(new D());
c.depend5(new D());
}
}
// 接口1
interface Interface1 {void operation1();
}
// 接口2
interface Interface2 {void operation2();
void operation3();
}
// 接口3
interface Interface3 {void operation4();
void operation5();
}
class B implements Interface1, Interface2 {public void operation1() {System.out.println("B 實(shí)現(xiàn)了 operation1");
}
public void operation2() {System.out.println("B 實(shí)現(xiàn)了 operation2");
}
public void operation3() {System.out.println("B 實(shí)現(xiàn)了 operation3");
}
}
class D implements Interface1, Interface3 {public void operation1() {System.out.println("D 實(shí)現(xiàn)了 operation1");
}
public void operation4() {System.out.println("D 實(shí)現(xiàn)了 operation4");
}
public void operation5() {System.out.println("D 實(shí)現(xiàn)了 operation5");
}
}
class A {// A 類(lèi)通過(guò)接口Interface1,Interface2 依賴(lài)(使用) B類(lèi),但是只會(huì)用到1,2,3方法
public void depend1(Interface1 i) {i.operation1();
}
public void depend2(Interface2 i) {i.operation2();
}
public void depend3(Interface2 i) {i.operation3();
}
}
class C {// C 類(lèi)通過(guò)接口Interface1,Interface3 依賴(lài)(使用) D類(lèi),但是只會(huì)用到1,4,5方法
public void depend1(Interface1 i) {i.operation1();
}
public void depend4(Interface3 i) {i.operation4();
}
public void depend5(Interface3 i) {i.operation5();
}
}
2.5 依賴(lài)倒轉(zhuǎn)原則
2.5.1基本介紹依賴(lài)倒轉(zhuǎn)原則(Dependence Inversion Principle)是指:
請(qǐng)編程完成 Person 接收消息 的功能。
public class DependecyInversion {public static void main(String[] args) {Person person = new Person();
person.receive(new Email());
}
}
class Email {public String getInfo() {return "電子郵件信息: hello,world";
}
}
//完成Person接收消息的功能
//方式1分析
//1. 簡(jiǎn)單,比較容易想到
//2. 如果我們獲取的對(duì)象是 微信,短信等等,則新增類(lèi),同時(shí)Perons也要增加相應(yīng)的接收方法
//3. 解決思路:引入一個(gè)抽象的接口IReceiver, 表示接收者, 這樣Person類(lèi)與接口IReceiver發(fā)生依賴(lài)
// 因?yàn)镋mail, WeiXin 等等屬于接收的范圍,他們各自實(shí)現(xiàn)IReceiver 接口就ok, 這樣我們就符號(hào)依賴(lài)倒轉(zhuǎn)原則
class Person {public void receive(Email email ) {System.out.println(email.getInfo());
}
}
package com.atguigu.principle.inversion.improve;
public class DependecyInversion {public static void main(String[] args) {//客戶(hù)端無(wú)需改變
Person person = new Person();
person.receive(new Email());
person.receive(new WeiXin());
}
}
//定義接口
interface IReceiver {public String getInfo();
}
class Email implements IReceiver {public String getInfo() {return "電子郵件信息: hello,world";
}
}
//增加微信
class WeiXin implements IReceiver {public String getInfo() {return "微信信息: hello,ok";
}
}
//方式2
class Person {//這里我們是對(duì)接口的依賴(lài)
public void receive(IReceiver receiver ) {System.out.println(receiver.getInfo());
}
}
2.5.3依賴(lài)關(guān)系傳遞的三種方式和應(yīng)用案例package com.atguigu.principle.inversion.improve;
public class DependencyPass {public static void main(String[] args) {// TODO Auto-generated method stub
ChangHong changHong = new ChangHong();
// OpenAndClose openAndClose = new OpenAndClose();
// openAndClose.open(changHong);
//通過(guò)構(gòu)造器進(jìn)行依賴(lài)傳遞
// OpenAndClose openAndClose = new OpenAndClose(changHong);
// openAndClose.open();
//通過(guò)setter方法進(jìn)行依賴(lài)傳遞
OpenAndClose openAndClose = new OpenAndClose();
openAndClose.setTv(changHong);
openAndClose.open();
}
}
// 方式1: 通過(guò)接口傳遞實(shí)現(xiàn)依賴(lài)
// 開(kāi)關(guān)的接口
// interface IOpenAndClose {// public void open(ITV tv); //抽象方法,接收接口
// }
//
// interface ITV { //ITV接口
// public void play();
// }
//
// class ChangHong implements ITV {//
// @Override
// public void play() {// // TODO Auto-generated method stub
// System.out.println("長(zhǎng)虹電視機(jī),打開(kāi)");
// }
//
// }
實(shí)現(xiàn)接口
// class OpenAndClose implements IOpenAndClose{// public void open(ITV tv){// tv.play();
// }
// }
// 方式2: 通過(guò)構(gòu)造方法依賴(lài)傳遞
// interface IOpenAndClose {// public void open(); //抽象方法
// }
// interface ITV { //ITV接口
// public void play();
// }
// class OpenAndClose implements IOpenAndClose{// public ITV tv; //成員
// public OpenAndClose(ITV tv){ //構(gòu)造器
// this.tv = tv;
// }
// public void open(){// this.tv.play();
// }
// }
// 方式3 , 通過(guò)setter方法傳遞
interface IOpenAndClose {public void open(); // 抽象方法
public void setTv(ITV tv);
}
interface ITV {// ITV接口
public void play();
}
class OpenAndClose implements IOpenAndClose {private ITV tv;
public void setTv(ITV tv) {this.tv = tv;
}
public void open() {this.tv.play();
}
}
class ChangHong implements ITV {@Override
public void play() {// TODO Auto-generated method stub
System.out.println("長(zhǎng)虹電視機(jī),打開(kāi)");
}
}
2.5.4依賴(lài)倒轉(zhuǎn)原則的注意事項(xiàng)和細(xì)節(jié)該看個(gè)程序, 思考下問(wèn)題和解決思路
public class Liskov {public static void main(String[] args) {// TODO Auto-generated method stub
A a = new A();
System.out.println("11-3=" + a.func1(11, 3));
System.out.println("1-8=" + a.func1(1, 8));
System.out.println("-----------------------");
B b = new B();
System.out.println("11-3=" + b.func1(11, 3));//這里本意是求出11-3
System.out.println("1-8=" + b.func1(1, 8));// 1-8
System.out.println("11+3+9=" + b.func2(11, 3));
}
}
// A類(lèi)
class A {// 返回兩個(gè)數(shù)的差
public int func1(int num1, int num2) {return num1 - num2;
}
}
// B類(lèi)繼承了A
// 增加了一個(gè)新功能:完成兩個(gè)數(shù)相加,然后和9求和
class B extends A {//這里,重寫(xiě)了A類(lèi)的方法, 可能是無(wú)意識(shí)
public int func1(int a, int b) {return a + b;
}
public int func2(int a, int b) {return func1(a, b) + 9;
}
}
2.6.4解決方法public class Liskov {public static void main(String[] args) {// TODO Auto-generated method stub
A a = new A();
System.out.println("11-3=" + a.func1(11, 3));
System.out.println("1-8=" + a.func1(1, 8));
System.out.println("-----------------------");
B b = new B();
//因?yàn)锽類(lèi)不再繼承A類(lèi),因此調(diào)用者,不會(huì)再func1是求減法
//調(diào)用完成的功能就會(huì)很明確
System.out.println("11+3=" + b.func1(11, 3));//這里本意是求出11+3
System.out.println("1+8=" + b.func1(1, 8));// 1+8
System.out.println("11+3+9=" + b.func2(11, 3));
//使用組合仍然可以使用到A類(lèi)相關(guān)方法
System.out.println("11-3=" + b.func3(11, 3));// 這里本意是求出11-3
}
}
//創(chuàng)建一個(gè)更加基礎(chǔ)的基類(lèi)
class Base {//把更加基礎(chǔ)的方法和成員寫(xiě)到Base類(lèi)
}
// A類(lèi)
class A extends Base {// 返回兩個(gè)數(shù)的差
public int func1(int num1, int num2) {return num1 - num2;
}
}
// B類(lèi)繼承了A
// 增加了一個(gè)新功能:完成兩個(gè)數(shù)相加,然后和9求和
class B extends Base {//如果B需要使用A類(lèi)的方法,使用組合關(guān)系
private A a = new A();
//這里,重寫(xiě)了A類(lèi)的方法, 可能是無(wú)意識(shí)
public int func1(int a, int b) {return a + b;
}
public int func2(int a, int b) {return func1(a, b) + 9;
}
//我們?nèi)匀幌胧褂肁的方法
public int func3(int a, int b) {return this.a.func1(a, b);
}
}
2.7 開(kāi)閉原則
2.7.1基本介紹? 看一個(gè)畫(huà)圖形的功能。
類(lèi)圖設(shè)計(jì),如下:
? 代碼演示
package com.atguigu.principle.ocp;
public class Ocp {public static void main(String[] args) {//使用看看存在的問(wèn)題
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
graphicEditor.drawShape(new Triangle());
}
}
//這是一個(gè)用于繪圖的類(lèi) [使用方]
class GraphicEditor {//接收Shape對(duì)象,然后根據(jù)type,來(lái)繪制不同的圖形
public void drawShape(Shape s) {if (s.m_type == 1)
drawRectangle(s);
else if (s.m_type == 2)
drawCircle(s);
else if (s.m_type == 3)
drawTriangle(s);
}
//繪制矩形
public void drawRectangle(Shape r) {System.out.println(" 繪制矩形 ");
}
//繪制圓形
public void drawCircle(Shape r) {System.out.println(" 繪制圓形 ");
}
//繪制三角形
public void drawTriangle(Shape r) {System.out.println(" 繪制三角形 ");
}
}
//Shape類(lèi),基類(lèi)
class Shape {int m_type;
}
class Rectangle extends Shape {Rectangle() {super.m_type = 1;
}
}
class Circle extends Shape {Circle() {super.m_type = 2;
}
}
//新增畫(huà)三角形
class Triangle extends Shape {Triangle() {super.m_type = 3;
}
}
2.7.3方式 1 的優(yōu)缺點(diǎn)思路:把創(chuàng)建 Shape 類(lèi)做成抽象類(lèi),并提供一個(gè)抽象的 draw 方法,讓子類(lèi)去實(shí)現(xiàn)即可,這樣我們有新的圖形種類(lèi)時(shí),只需要讓新的圖形類(lèi)繼承 Shape,并實(shí)現(xiàn) draw 方法即可,使用方的代碼就不需要修->滿(mǎn)足了開(kāi)閉原則
改進(jìn)后的代碼:
package com.atguigu.principle.ocp.improve;
public class Ocp {public static void main(String[] args) {//使用看看存在的問(wèn)題
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawShape(new Rectangle());
graphicEditor.drawShape(new Circle());
graphicEditor.drawShape(new Triangle());
graphicEditor.drawShape(new OtherGraphic());
}
}
//這是一個(gè)用于繪圖的類(lèi) [使用方]
class GraphicEditor {//接收Shape對(duì)象,調(diào)用draw方法
public void drawShape(Shape s) {s.draw();
}
}
//Shape類(lèi),基類(lèi)
abstract class Shape {int m_type;
public abstract void draw();//抽象方法
}
class Rectangle extends Shape {Rectangle() {super.m_type = 1;
}
@Override
public void draw() {// TODO Auto-generated method stub
System.out.println(" 繪制矩形 ");
}
}
class Circle extends Shape {Circle() {super.m_type = 2;
}
@Override
public void draw() {// TODO Auto-generated method stub
System.out.println(" 繪制圓形 ");
}
}
//新增畫(huà)三角形
class Triangle extends Shape {Triangle() {super.m_type = 3;
}
@Override
public void draw() {// TODO Auto-generated method stub
System.out.println(" 繪制三角形 ");
}
}
//新增一個(gè)圖形
class OtherGraphic extends Shape {OtherGraphic() {super.m_type = 4;
}
@Override
public void draw() {// TODO Auto-generated method stub
System.out.println(" 繪制其它圖形 ");
}
}
2.8 迪米特法則
2.8.1基本介紹package com.atguigu.principle.demeter;
import java.util.ArrayList;
import java.util.List;
//客戶(hù)端
public class Demeter1 {public static void main(String[] args) {//創(chuàng)建了一個(gè) SchoolManager 對(duì)象
SchoolManager schoolManager = new SchoolManager();
//輸出學(xué)院的員工id 和 學(xué)??偛康膯T工信息
schoolManager.printAllEmployee(new CollegeManager());
}
}
//學(xué)??偛繂T工類(lèi)
class Employee {private String id;
public void setId(String id) {this.id = id;
}
public String getId() {return id;
}
}
//學(xué)院的員工類(lèi)
class CollegeEmployee {private String id;
public void setId(String id) {this.id = id;
}
public String getId() {return id;
}
}
//管理學(xué)院?jiǎn)T工的管理類(lèi)
class CollegeManager {//返回學(xué)院的所有員工
public ListgetAllEmployee() {Listlist = new ArrayList();
for (int i = 0; i< 10; i++) {//這里我們?cè)黾恿?0個(gè)員工到 list
CollegeEmployee emp = new CollegeEmployee();
emp.setId("學(xué)院?jiǎn)T工id= " + i);
list.add(emp);
}
return list;
}
}
//學(xué)校管理類(lèi)
//分析 SchoolManager 類(lèi)的直接朋友類(lèi)有哪些 Employee、CollegeManager
//CollegeEmployee 不是 直接朋友 而是一個(gè)陌生類(lèi),這樣違背了 迪米特法則
class SchoolManager {//返回學(xué)??偛康膯T工
public ListgetAllEmployee() {Listlist = new ArrayList();
for (int i = 0; i< 5; i++) {//這里我們?cè)黾恿?個(gè)員工到 list
Employee emp = new Employee();
emp.setId("學(xué)??偛繂T工id= " + i);
list.add(emp);
}
return list;
}
//該方法完成輸出學(xué)校總部和學(xué)院?jiǎn)T工信息(id)
void printAllEmployee(CollegeManager sub) { //分析問(wèn)題
//1. 這里的 CollegeEmployee 不是 SchoolManager的直接朋友
//2. CollegeEmployee 是以局部變量方式出現(xiàn)在 SchoolManager
//3. 違反了 迪米特法則
//獲取到學(xué)院?jiǎn)T工
Listlist1 = sub.getAllEmployee();
System.out.println("------------學(xué)院?jiǎn)T工------------");
for (CollegeEmployee e : list1) { System.out.println(e.getId());
}
//獲取到學(xué)??偛繂T工
Listlist2 = this.getAllEmployee();
System.out.println("------------學(xué)??偛繂T工------------");
for (Employee e : list2) { System.out.println(e.getId());
}
}
}
2.8.3應(yīng)用實(shí)例改進(jìn)package com.atguigu.principle.demeter.improve;
import java.util.ArrayList;
import java.util.List;
//客戶(hù)端
public class Demeter1 {public static void main(String[] args) {System.out.println("~~~使用迪米特法則的改進(jìn)~~~");
//創(chuàng)建了一個(gè) SchoolManager 對(duì)象
SchoolManager schoolManager = new SchoolManager();
//輸出學(xué)院的員工id 和 學(xué)??偛康膯T工信息
schoolManager.printAllEmployee(new CollegeManager());
}
}
//學(xué)校總部員工類(lèi)
class Employee {private String id;
public void setId(String id) {this.id = id;
}
public String getId() {return id;
}
}
//學(xué)院的員工類(lèi)
class CollegeEmployee {private String id;
public void setId(String id) {this.id = id;
}
public String getId() {return id;
}
}
//管理學(xué)院?jiǎn)T工的管理類(lèi)
class CollegeManager {//返回學(xué)院的所有員工
public ListgetAllEmployee() {Listlist = new ArrayList();
for (int i = 0; i< 10; i++) {//這里我們?cè)黾恿?0個(gè)員工到 list
CollegeEmployee emp = new CollegeEmployee();
emp.setId("學(xué)院?jiǎn)T工id= " + i);
list.add(emp);
}
return list;
}
//輸出學(xué)院?jiǎn)T工的信息
public void printEmployee() {//獲取到學(xué)院?jiǎn)T工
Listlist1 = getAllEmployee();
System.out.println("------------學(xué)院?jiǎn)T工------------");
for (CollegeEmployee e : list1) { System.out.println(e.getId());
}
}
}
//學(xué)校管理類(lèi)
//分析 SchoolManager 類(lèi)的直接朋友類(lèi)有哪些 Employee、CollegeManager
//CollegeEmployee 不是 直接朋友 而是一個(gè)陌生類(lèi),這樣違背了 迪米特法則
class SchoolManager {//返回學(xué)??偛康膯T工
public ListgetAllEmployee() {Listlist = new ArrayList();
for (int i = 0; i< 5; i++) {//這里我們?cè)黾恿?個(gè)員工到 list
Employee emp = new Employee();
emp.setId("學(xué)校總部員工id= " + i);
list.add(emp);
}
return list;
}
//該方法完成輸出學(xué)??偛亢蛯W(xué)院?jiǎn)T工信息(id)
void printAllEmployee(CollegeManager sub) { //分析問(wèn)題
//1. 將輸出學(xué)院的員工方法,封裝到CollegeManager
sub.printEmployee();
//獲取到學(xué)??偛繂T工
Listlist2 = this.getAllEmployee();
System.out.println("------------學(xué)校總部員工------------");
for (Employee e : list2) { System.out.println(e.getId());
}
}
}
2.8.4迪米特法則注意事項(xiàng)和細(xì)節(jié)原則是盡量使用合成/聚合的方式,而不是使用繼承
畫(huà) UML 圖與寫(xiě)文章差不多,都是把自己的思想描述給別人看,關(guān)鍵在于思路和條理,UML 圖分類(lèi):
public class Person{//代碼形式->類(lèi)圖
private Integer id;
private String name;
public void setName(String name){this.name=name;
}
public String getName(){return name;
}
}
? 只要是在類(lèi)中用到了對(duì)方,那么他們之間就存在依賴(lài)關(guān)系。如果沒(méi)有對(duì)方,連編繹都通過(guò)不了。
public class PersonServiceBean {private PersonDao personDao;//類(lèi)
public void save(Person person) {}
public IDCard getIDCard(Integer personid) {}
public void modify() {Department department = new Department();
}
}
public class PersonDao {}
public class IDCard {}
public class Person {}
public class Department {}
? 對(duì)應(yīng)的類(lèi)圖:
? 小結(jié)
? 泛化關(guān)系實(shí)際上就是繼承關(guān)系,他是依賴(lài)關(guān)系的特例
public abstract class DaoSupport {public void save(Object entity) {}
public void delete(Object id) {}
}
public class PersonServiceBean extends Daosupport {}
? 對(duì)應(yīng)的類(lèi)圖
? 小結(jié):
實(shí)現(xiàn)關(guān)系實(shí)際上就是A 類(lèi)實(shí)現(xiàn) B 接口,他是依賴(lài)關(guān)系的特例
public interface PersonService {public void delete(Interger id);
}
public class PersonServiceBean implements PersonService {public void delete(Interger id) {}
}
=>類(lèi)圖
聚合關(guān)系(Aggregation)表示的是整體和部分的關(guān)系,整體與部分可以分開(kāi)。聚合關(guān)系是關(guān)聯(lián)關(guān)系的特例,所以他具有關(guān)聯(lián)的導(dǎo)航性與多重性。
如:一臺(tái)電腦由鍵盤(pán)(keyboard)、顯示器(monitor),鼠標(biāo)等組成;組成電腦的各個(gè)配件是可以從電腦上分離出來(lái)的,使用帶空心菱形的實(shí)線(xiàn)來(lái)表示:
組合關(guān)系:也是整體與部分的關(guān)系,但是整體與部分不可以分開(kāi)。
再看一個(gè)案例:在程序中我們定義實(shí)體:Person 與 IDCard、Head, 那么 Head 和 Person 就是組合,IDCard和Person 就是聚合。
但是如果在程序中 Person 實(shí)體中定義了對(duì) IDCard 進(jìn)行級(jí)聯(lián)刪除,即刪除 Person 時(shí)連同IDCard 一起刪除,那么 IDCard 和 Person 就是組合了.
public class Person {private IDCard card;
private Head head = new Head();
}
public class IDCard {}
public class Head {}
對(duì)應(yīng)的類(lèi)圖:
案例 2
public class Computer {private Mouse mouse = new Mouse(); //鼠標(biāo)可以和 computer 不能分離
private Moniter moniter = new Moniter();//顯示器可以和 Computer 不能分離
public void setMouse(Mouse mouse) {this.mouse = mouse;
}
public void setMoniter(Moniter moniter) {this.moniter = moniter;
}
}
public class Mouse {}
public class Moniter {}
對(duì)應(yīng)的類(lèi)圖
設(shè)計(jì)模式分為三種類(lèi)型,共 23 種
所謂類(lèi)的單例設(shè)計(jì)模式,就是采取一定的方法保證在整個(gè)的軟件系統(tǒng)中,對(duì)某個(gè)類(lèi)只能存在一個(gè)對(duì)象實(shí)例,并且該類(lèi)只提供一個(gè)取得其對(duì)象實(shí)例的方法(靜態(tài)方法)。
比如 Hibernate 的 SessionFactory,它充當(dāng)數(shù)據(jù)存儲(chǔ)源的代理,并負(fù)責(zé)創(chuàng)建 Session 對(duì)象。SessionFactory并不是輕量級(jí)的,一般情況下,一個(gè)項(xiàng)目通常只需要一個(gè) SessionFactory 就夠,這是就會(huì)使用到單例模式。
單例模式有八種方式:
1) 餓漢式(靜態(tài)常量)
2) 餓漢式(靜態(tài)代碼塊)
3) 懶漢式(線(xiàn)程不安全)
4) 懶漢式(線(xiàn)程安全,同步方法)
5) 懶漢式(線(xiàn)程安全,同步代碼塊)
6) 雙重檢查
7) 靜態(tài)內(nèi)部類(lèi)
8) 枚舉
餓漢式(靜態(tài)常量)應(yīng)用實(shí)例
步驟如下:
package com.atguigu.singleton.type1;
public class SingletonTest01 {public static void main(String[] args) {//測(cè)試
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
//餓漢式(靜態(tài)變量)
class Singleton { //1. 構(gòu)造器私有化, 外部能new
private Singleton() { }
//2.本類(lèi)內(nèi)部創(chuàng)建對(duì)象實(shí)例
private final static Singleton instance = new Singleton();
//3. 提供一個(gè)公有的靜態(tài)方法,返回實(shí)例對(duì)象
public static Singleton getInstance() {return instance;
}
}
? 優(yōu)缺點(diǎn)說(shuō)明:
? 代碼演示:
package com.atguigu.singleton.type2;
public class SingletonTest02 {public static void main(String[] args) {//測(cè)試
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
//餓漢式(靜態(tài)變量)
class Singleton { //1. 構(gòu)造器私有化, 外部能new
private Singleton() { }
//2.本類(lèi)內(nèi)部創(chuàng)建對(duì)象實(shí)例
private static Singleton instance;
static {// 在靜態(tài)代碼塊中,創(chuàng)建單例對(duì)象
instance = new Singleton();
}
//3. 提供一個(gè)公有的靜態(tài)方法,返回實(shí)例對(duì)象
public static Singleton getInstance() {return instance;
}
}
? 優(yōu)缺點(diǎn)說(shuō)明:
? 代碼演示:
package com.atguigu.singleton.type3;
public class SingletonTest03 {public static void main(String[] args) {System.out.println("懶漢式1 , 線(xiàn)程不安全~");
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
class Singleton {private static Singleton instance;
private Singleton() {}
//提供一個(gè)靜態(tài)的公有方法,當(dāng)使用到該方法時(shí),才去創(chuàng)建 instance
//即懶漢式
public static Singleton getInstance() {if(instance == null) { instance = new Singleton();
}
return instance;
}
}
? 優(yōu)缺點(diǎn)說(shuō)明:
? 代碼演示:
package com.atguigu.singleton.type4;
public class SingletonTest04 {public static void main(String[] args) {System.out.println("懶漢式2 , 線(xiàn)程安全~");
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
// 懶漢式(線(xiàn)程安全,同步方法)
class Singleton {private static Singleton instance;
private Singleton() {}
//提供一個(gè)靜態(tài)的公有方法,加入同步處理的代碼,解決線(xiàn)程安全問(wèn)題
//即懶漢式
public static synchronized Singleton getInstance() {if(instance == null) { instance = new Singleton();
}
return instance;
}
}
? 優(yōu)缺點(diǎn)說(shuō)明:
不推薦使用
? 代碼演示
package com.atguigu.singleton.type6;
public class SingletonTest06 {public static void main(String[] args) {System.out.println("雙重檢查");
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
// 懶漢式(線(xiàn)程安全,同步方法)
class Singleton {private static volatile Singleton instance;
private Singleton() {}
//提供一個(gè)靜態(tài)的公有方法,加入雙重檢查代碼,解決線(xiàn)程安全問(wèn)題, 同時(shí)解決懶加載問(wèn)題
//同時(shí)保證了效率, 推薦使用
public static synchronized Singleton getInstance() {if(instance == null) { synchronized (Singleton.class) { if(instance == null) {instance = new Singleton();
}
}
}
return instance;
}
}
? 優(yōu)缺點(diǎn)說(shuō)明:
package com.atguigu.singleton.type7;
public class SingletonTest07 {public static void main(String[] args) {System.out.println("使用靜態(tài)內(nèi)部類(lèi)完成單例模式");
Singleton instance = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance == instance2); // true
System.out.println("instance.hashCode=" + instance.hashCode());
System.out.println("instance2.hashCode=" + instance2.hashCode());
}
}
// 靜態(tài)內(nèi)部類(lèi)完成, 推薦使用
class Singleton {private static volatile Singleton instance;
//構(gòu)造器私有化
private Singleton() {}
//寫(xiě)一個(gè)靜態(tài)內(nèi)部類(lèi),該類(lèi)中有一個(gè)靜態(tài)屬性 Singleton
private static class SingletonInstance {private static final Singleton INSTANCE = new Singleton();
}
//提供一個(gè)靜態(tài)的公有方法,直接返回SingletonInstance.INSTANCE
public static synchronized Singleton getInstance() { return SingletonInstance.INSTANCE;
}
}
? 優(yōu)缺點(diǎn)說(shuō)明:
? 代碼演示
package com.atguigu.singleton.type8;
public class SingletonTest08 {public static void main(String[] args) {Singleton instance = Singleton.INSTANCE;
Singleton instance2 = Singleton.INSTANCE;
System.out.println(instance == instance2);
System.out.println(instance.hashCode());
System.out.println(instance2.hashCode());
instance.sayOK();
}
}
//使用枚舉,可以實(shí)現(xiàn)單例, 推薦
enum Singleton {INSTANCE; //屬性
public void sayOK() {System.out.println("ok~");
}
}
? 優(yōu)缺點(diǎn)說(shuō)明:
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)頁(yè)題目:java設(shè)計(jì)模式-創(chuàng)新互聯(lián)
網(wǎng)站地址:http://chinadenli.net/article48/ghjep.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、定制網(wǎng)站、云服務(wù)器、小程序開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容