日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
設(shè)計(jì)之魅:高質(zhì)量面向?qū)ο笤O(shè)計(jì)的秘密

設(shè)計(jì)模式是在軟件設(shè)計(jì)中用于解決常見問題的經(jīng)過驗(yàn)證的解決方案。設(shè)計(jì)模式并不是代碼或庫,而是一種解決問題的思考方式。在使用設(shè)計(jì)模式時(shí),需要考慮一些基本的設(shè)計(jì)原則,這些原則有助于構(gòu)建靈活、可維護(hù)和可擴(kuò)展的軟件系統(tǒng)。以下是一些常見的設(shè)計(jì)原則:

創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站建設(shè)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、安達(dá)網(wǎng)絡(luò)推廣、小程序設(shè)計(jì)、安達(dá)網(wǎng)絡(luò)營(yíng)銷、安達(dá)企業(yè)策劃、安達(dá)品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供安達(dá)建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com

單一職責(zé)原則(Single Responsibility Principle - SRP):

它指導(dǎo)我們確保一個(gè)類只有一個(gè)責(zé)任。類的責(zé)任應(yīng)該是單一的,即一個(gè)類應(yīng)該只有一個(gè)引起它變化的原因。這有助于提高類的內(nèi)聚性,使得類更加容易理解、修改和維護(hù)。

// 違反單一職責(zé)原則的例子
class Report {
    private String title;
    private String content;

    public Report(String title, String content) {
        this.title = title;
        this.content = content;
    }

    public void generateReport() {
        // 生成報(bào)告的業(yè)務(wù)邏輯
        System.out.println("Generating report for " + title + " with content: " + content);
    }

    public void saveToFile() {
        // 將報(bào)告保存到文件的業(yè)務(wù)邏輯
        String filename = title.replace(" ", "_") + ".txt";
        // 實(shí)際保存到文件的代碼略
        System.out.println("Report saved to " + filename);
    }
}

// 遵循單一職責(zé)原則的例子
class Report {
    private String title;
    private String content;

    public Report(String title, String content) {
        this.title = title;
        this.content = content;
    }

    public void generateReport() {
        // 生成報(bào)告的業(yè)務(wù)邏輯
        System.out.println("Generating report for " + title + " with content: " + content);
    }
}

class FileSaver {
    public static void saveToFile(Report report) {
        // 將報(bào)告保存到文件的業(yè)務(wù)邏輯
        String filename = report.getTitle().replace(" ", "_") + ".txt";
        // 實(shí)際保存到文件的代碼略
        System.out.println("Report saved to " + filename);
    }
}

// 上述例子中,Report 類負(fù)責(zé)生成報(bào)告,而 FileSaver 類負(fù)責(zé)將報(bào)告保存到文件。這樣,每個(gè)類都有一個(gè)清晰的責(zé)任,遵循了單一職責(zé)原則。

在上述例子中,第一個(gè)示例中的 Report 類違反了單一職責(zé)原則,因?yàn)樗?fù)責(zé)生成報(bào)告和保存報(bào)告到文件兩個(gè)不同的責(zé)任。在第二個(gè)示例中,將這兩個(gè)責(zé)任分別放在 Report 類和 FileSaver 類中,遵循了單一職責(zé)原則,使得每個(gè)類都更加簡(jiǎn)單和可維護(hù)。這樣的設(shè)計(jì)有助于將系統(tǒng)的不同部分解耦,提高代碼的靈活性和可擴(kuò)展性。

一個(gè)類應(yīng)該只有一個(gè)引起變化的原因。換句話說,一個(gè)類應(yīng)該只有一個(gè)責(zé)任。

開放/封閉原則(Open/Closed Principle - OCP):

由勃蘭特·梅耶(Bertrand Meyer)提出。該原則表明一個(gè)軟件實(shí)體(類、模塊、函數(shù)等)應(yīng)該對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。簡(jiǎn)而言之,當(dāng)需要添加新功能時(shí),應(yīng)該通過擴(kuò)展而不是修改現(xiàn)有代碼來實(shí)現(xiàn)。

具體來說,開放/封閉原則的核心思想是:

開放(Open):

軟件實(shí)體應(yīng)該可以在不修改它的源代碼的情況下進(jìn)行擴(kuò)展。

新功能應(yīng)該通過添加新代碼來實(shí)現(xiàn),而不是通過修改已有代碼。

封閉(Closed):

已有的軟件實(shí)體不應(yīng)該被修改,因?yàn)樾薷目赡芤胄碌腻e(cuò)誤或影響現(xiàn)有功能的穩(wěn)定性。

這樣的設(shè)計(jì)使得系統(tǒng)更加穩(wěn)定,因?yàn)椴恍枰薷默F(xiàn)有代碼,只需要添加新的代碼。這也有助于降低代碼的耦合性,提高代碼的可維護(hù)性和可擴(kuò)展性。

// 違反開放/封閉原則的例子
class Rectangle {
    public double width;
    public double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
}

class AreaCalculator {
    public double calculateRectangleArea(Rectangle rectangle) {
        return rectangle.width * rectangle.height;
    }
}

// 上述代碼違反了開放/封閉原則,如果要添加一個(gè)新的形狀(例如圓形),就需要修改 AreaCalculator 類。

// 遵循開放/封閉原則的例子
interface Shape {
    double calculateArea();
}

class Rectangle implements Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double calculateArea() {
        return width * height;
    }
}

class Circle implements Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

class AreaCalculator {
    public double calculateShapeArea(Shape shape) {
        return shape.calculateArea();
    }
}

// 上述代碼遵循了開放/封閉原則,通過引入 Shape 接口和不同的形狀類,可以輕松地添加新的形狀而無需修改 AreaCalculator 類。

在遵循開放/封閉原則的例子中,通過引入一個(gè) Shape 接口和不同的形狀類(例如 Rectangle 和 Circle),可以輕松地添加新的形狀而無需修改 AreaCalculator 類。這樣,系統(tǒng)的擴(kuò)展性得到了提高,同時(shí)保持了對(duì)現(xiàn)有代碼的封閉性。

軟件實(shí)體(類、模塊、函數(shù)等)應(yīng)該對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。這意味著在不修改現(xiàn)有代碼的情況下,可以通過添加新的代碼來擴(kuò)展系統(tǒng)的功能。

里氏替換原則(Liskov Substitution Principle - LSP):

由計(jì)算機(jī)科學(xué)家巴巴拉·利斯科夫(Barbara Liskov)提出。該原則指導(dǎo)著子類型(派生類或子類)如何與基類型(基類或父類)進(jìn)行替換,以確保程序的正確性和一致性。

如果對(duì)每一個(gè)類型為 S 的對(duì)象 o1,都有類型為 T 的對(duì)象 o2,使得以 T 定義的所有程序 P 在所有的對(duì)象 o1 都替換成 o2 時(shí),程序 P 的行為沒有發(fā)生變化,那么類型 S 是類型 T 的子類型。

換句話說,如果子類型可以替換父類型而不影響程序的正確性,那么這個(gè)子類型是符合里氏替換原則的。

// 違反里氏替換原則的例子

class Rectangle {
    protected int width;
    protected int height;

    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int calculateArea() {
        return width * height;
    }
}

class Square extends Rectangle {
    @Override
    public void setWidth(int width) {
        super.setWidth(width);
        super.setHeight(width);
    }

    @Override
    public void setHeight(int height) {
        super.setHeight(height);
        super.setWidth(height);
    }
}

// 上述代碼違反了里氏替換原則,因?yàn)樵赟quare類中重寫了setWidth和setHeight方法,導(dǎo)致Square對(duì)象在替換Rectangle對(duì)象時(shí)可能會(huì)引發(fā)意料之外的行為。

// 遵循里氏替換原則的例子

class Shape {
    protected int width;
    protected int height;

    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int calculateArea() {
        return width * height;
    }
}

class Rectangle extends Shape {
    // 省略特有的方法或?qū)傩?}

class Square extends Shape {
    @Override
    public void setWidth(int side) {
        super.setWidth(side);
        super.setHeight(side);
    }

    @Override
    public void setHeight(int side) {
        super.setHeight(side);
        super.setWidth(side);
    }
}

// 上述代碼遵循了里氏替換原則,因?yàn)镾quare類繼承自Shape類,沒有修改基類的行為,而是通過適當(dāng)?shù)姆绞綌U(kuò)展了基類的功能。

在遵循里氏替換原則的例子中,Square類不再繼承自Rectangle類,而是繼承自一個(gè)通用的Shape類,確保子類型可以被替換而不引起意外的行為變化。通過這種方式,程序可以更靈活地使用不同的形狀類型,而不必?fù)?dān)心替換時(shí)可能引發(fā)的問題。

子類型必須能夠替換其基類型而不改變程序的正確性。如果一個(gè)類是某個(gè)抽象類的子類,那么它應(yīng)該能夠替代該抽象類的任何地方,并且程序的行為不會(huì)改變。

依賴倒置原則(Dependency Inversion Principle - DIP):

由羅伯特·馬丁(Robert C. Martin)提出。該原則主要有兩個(gè)核心觀點(diǎn):

  • 高層模塊不應(yīng)該依賴于低層模塊,二者都應(yīng)該依賴于抽象。
  • 抽象不應(yīng)該依賴于細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴于抽象。

在設(shè)計(jì)系統(tǒng)時(shí),應(yīng)該通過依賴于抽象而不是具體實(shí)現(xiàn)來減少模塊之間的耦合。高層模塊和低層模塊都應(yīng)該依賴于通用的抽象,而不是彼此直接依賴。這有助于提高系統(tǒng)的靈活性、可維護(hù)性和可擴(kuò)展性。

// 違反依賴倒置原則的例子

class LightBulb {
    public void turnOn() {
        System.out.println("LightBulb: Bulb turned on...");
    }

    public void turnOff() {
        System.out.println("LightBulb: Bulb turned off...");
    }
}

class Switch {
    private LightBulb bulb;

    public Switch() {
        this.bulb = new LightBulb();
    }

    public void operate() {
        if (bulb != null) {
            if (bulb.isOn()) {
                bulb.turnOff();
            } else {
                bulb.turnOn();
            }
        }
    }
}

// 上述代碼違反了依賴倒置原則,因?yàn)镾witch類直接依賴于具體的LightBulb類。

// 遵循依賴倒置原則的例子

interface Switchable {
    void turnOn();

    void turnOff();
}

class LightBulb implements Switchable {
    @Override
    public void turnOn() {
        System.out.println("LightBulb: Bulb turned on...");
    }

    @Override
    public void turnOff() {
        System.out.println("LightBulb: Bulb turned off...");
    }
}

class Switch {
    private Switchable device;

    public Switch(Switchable device) {
        this.device = device;
    }

    public void operate() {
        if (device != null) {
            if (device.isOn()) {
                device.turnOff();
            } else {
                device.turnOn();
            }
        }
    }
}

// 上述代碼遵循了依賴倒置原則,Switch類依賴于通用的Switchable接口而不是具體的LightBulb類。

在遵循依賴倒置原則的例子中,Switch 類不再直接依賴于 LightBulb 類,而是依賴于通用的 Switchable 接口。這樣,如果有其他類實(shí)現(xiàn)了 Switchable 接口,可以輕松地替換 LightBulb 類,而不影響 Switch 類的實(shí)現(xiàn)。這提高了系統(tǒng)的靈活性和可維護(hù)性。

高層模塊不應(yīng)該依賴于低層模塊,二者都應(yīng)該依賴于抽象。抽象不應(yīng)該依賴于細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴于抽象。這促使使用接口或抽象類來減少模塊之間的耦合。

接口隔離原則(Interface Segregation Principle - ISP):

接口隔離原則(Interface Segregation Principle - ISP)是面向?qū)ο笤O(shè)計(jì)中的一個(gè)原則,它強(qiáng)調(diào)一個(gè)類不應(yīng)該被強(qiáng)迫依賴于它不使用的接口。該原則的目標(biāo)是防止一個(gè)類因?yàn)閷?shí)現(xiàn)了不需要的接口而變得龐大臃腫,降低類的內(nèi)聚性。

接口隔離原則可以通過將大接口拆分成更小的、更具體的接口來實(shí)現(xiàn)。具體來說,一個(gè)類只應(yīng)該知道它需要使用的方法,而不需要了解其他不相關(guān)的方法。

// 違反接口隔離原則的例子

interface Worker {
    void work();

    void eat();
}

class Robot implements Worker {
    @Override
    public void work() {
        System.out.println("Robot is working...");
    }

    @Override
    public void eat() {
        // 空實(shí)現(xiàn),機(jī)器人無需進(jìn)食
    }
}

class Human implements Worker {
    @Override
    public void work() {
        System.out.println("Human is working...");
    }

    @Override
    public void eat() {
        System.out.println("Human is eating...");
    }
}

// 上述代碼違反了接口隔離原則,因?yàn)镽obot類實(shí)現(xiàn)了不需要的eat方法。

// 遵循接口隔離原則的例子

interface Workable {
    void work();
}

interface Eatable {
    void eat();
}

class Robot implements Workable {
    @Override
    public void work() {
        System.out.println("Robot is working...");
    }
}

class Human implements Workable, Eatable {
    @Override
    public void work() {
        System.out.println("Human is working...");
    }

    @Override
    public void eat() {
        System.out.println("Human is eating...");
    }
}

// 上述代碼遵循了接口隔離原則,將大接口拆分成Workable和Eatable兩個(gè)小接口,類只需要實(shí)現(xiàn)它們真正需要的接口。

在遵循接口隔離原則的例子中,將大接口拆分成 Workable 和 Eatable 兩個(gè)小接口。這樣,Robot 類只需實(shí)現(xiàn) Workable 接口,而 Human 類則同時(shí)實(shí)現(xiàn)了 Workable 和 Eatable 接口。這避免了類實(shí)現(xiàn)不需要的方法,提高了系統(tǒng)的靈活性和可維護(hù)性。

不應(yīng)該強(qiáng)迫客戶端依賴于它們不使用的接口。一個(gè)類不應(yīng)該被迫實(shí)現(xiàn)它用不到的接口。

合成/聚合復(fù)用原則(Composition/Aggregation Reuse Principle - CARP):

合成/聚合復(fù)用原則(Composition/Aggregation Reuse Principle - CARP)是面向?qū)ο笤O(shè)計(jì)中的一個(gè)原則,它強(qiáng)調(diào)在復(fù)用時(shí)優(yōu)先使用組合(Composition)和聚合(Aggregation),而不是繼承。該原則的核心思想是通過將現(xiàn)有的類組合在一起來創(chuàng)建新的類,而不是通過繼承現(xiàn)有類。

合成/聚合復(fù)用原則的主要原則有兩個(gè):

優(yōu)先使用合成(Composition):

通過將對(duì)象組合在一起來創(chuàng)建新的對(duì)象,而不是通過繼承現(xiàn)有類。這樣可以更靈活地構(gòu)建對(duì)象的行為,而不會(huì)產(chǎn)生繼承鏈的問題。

優(yōu)先使用聚合(Aggregation):

聚合是一種特殊的合成關(guān)系,表示一種“整體-部分”的關(guān)系,但整體和部分之間的生命周期可以獨(dú)立存在。這允許部分對(duì)象在沒有整體對(duì)象的情況下存在。與合成一樣,聚合也提供了更靈活的復(fù)用方式。

// 違反合成/聚合復(fù)用原則的例子

class Engine {
    public void start() {
        System.out.println("Engine starting...");
    }
}

class Car extends Engine {
    public void drive() {
        System.out.println("Car is driving...");
    }
}

// 上述代碼違反了合成/聚合復(fù)用原則,因?yàn)镃ar類通過繼承Engine類,導(dǎo)致Car和Engine之間形成了緊耦合的關(guān)系。

// 遵循合成/聚合復(fù)用原則的例子

class Engine {
    public void start() {
        System.out.println("Engine starting...");
    }
}

class Car {
    private Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }

    public void drive() {
        engine.start();
        System.out.println("Car is driving...");
    }
}

// 上述代碼遵循了合成/聚合復(fù)用原則,Car類通過組合引入了Engine類,而不是通過繼承。這降低了類之間的耦合性,使得系統(tǒng)更加靈活。

在遵循合成/聚合復(fù)用原則的例子中,Car 類通過組合引入了 Engine 類,而不是通過繼承。這降低了類之間的耦合性,使得系統(tǒng)更加靈活,更容易進(jìn)行復(fù)用和維護(hù)。使用合成和聚合的方式可以避免繼承鏈的問題,并提高系統(tǒng)的靈活性。

首選使用合成/聚合,而不是繼承。通過將現(xiàn)有類的實(shí)例組合到新的類中,而不是通過繼承現(xiàn)有類來實(shí)現(xiàn)代碼復(fù)用。

迪米特法則(Law of Demeter - LoD):

迪米特法則(Law of Demeter - LoD),也被稱為最少知識(shí)原則,是面向?qū)ο笤O(shè)計(jì)中的一項(xiàng)原則。迪米特法則強(qiáng)調(diào)一個(gè)對(duì)象應(yīng)該對(duì)其他對(duì)象有最少的了解,即一個(gè)類不應(yīng)該直接與其他類過多地發(fā)生相互作用。

一個(gè)對(duì)象應(yīng)該對(duì)其他對(duì)象保持最少的了解。只與你的直接朋友通信,而避免和陌生人通信。

這意味著一個(gè)類應(yīng)該盡量減少對(duì)其他類的引用,盡量減少依賴關(guān)系,以降低類之間的耦合度。通過保持對(duì)象之間的關(guān)系簡(jiǎn)單,可以提高系統(tǒng)的靈活性和可維護(hù)性。

// 違反迪米特法則的例子

class Teacher {
    public void instruct(Student student) {
        // 教師直接與學(xué)生對(duì)象發(fā)生交互
        student.study();
    }
}

class Student {
    public void study() {
        System.out.println("Student is studying...");
    }
}

// 上述代碼違反了迪米特法則,因?yàn)門eacher類直接與Student類發(fā)生了交互。

// 遵循迪米特法則的例子

class Teacher {
    public void instruct(StudentProxy studentProxy) {
        // 教師只與學(xué)生代理對(duì)象發(fā)生交互,而不直接與學(xué)生對(duì)象交互
        studentProxy.study();
    }
}

class Student {
    public void study() {
        System.out.println("Student is studying...");
    }
}

class StudentProxy {
    private Student student;

    public StudentProxy(Student student) {
        this.student = student;
    }

    public void study() {
        // 通過代理對(duì)象轉(zhuǎn)發(fā)請(qǐng)求給學(xué)生對(duì)象
        student.study();
    }
}

// 上述代碼遵循了迪米特法則,Teacher類只與StudentProxy類發(fā)生交互,而不直接與Student類發(fā)生交互。

在遵循迪米特法則的例子中,Teacher 類只與 StudentProxy 類發(fā)生交互,而不直接與 Student 類發(fā)生交互。這樣,Teacher 類不需要了解 Student 類的內(nèi)部實(shí)現(xiàn),通過 StudentProxy 類進(jìn)行間接的交互。這降低了類之間的耦合度,符合迪米特法則的要求。

一個(gè)軟件實(shí)體應(yīng)當(dāng)盡可能少地與其他實(shí)體發(fā)生相互作用。也被稱為最少知識(shí)原則。

在面向?qū)ο笤O(shè)計(jì)中,設(shè)計(jì)原則是指導(dǎo)我們創(chuàng)建靈活、可維護(hù)、可擴(kuò)展軟件系統(tǒng)的重要指導(dǎo)方針。每個(gè)設(shè)計(jì)原則都強(qiáng)調(diào)特定的方面,例如單一職責(zé)原則、開放/封閉原則、里氏替換原則、依賴倒置原則、接口隔離原則和合成/聚合復(fù)用原則。這些原則共同構(gòu)建了一個(gè)強(qiáng)大的設(shè)計(jì)基礎(chǔ),有助于在面對(duì)不斷變化的需求時(shí)更好地應(yīng)對(duì)挑戰(zhàn)。

在實(shí)際開發(fā)中,理解并應(yīng)用這些設(shè)計(jì)原則是至關(guān)重要的。它們提供了一組指導(dǎo)原則,幫助自己構(gòu)建出更加健壯和靈活的軟件系統(tǒng)。通過不斷學(xué)習(xí)和實(shí)踐,可以更好地運(yùn)用這些原則來創(chuàng)建高質(zhì)量的面向?qū)ο笤O(shè)計(jì)。


網(wǎng)站欄目:設(shè)計(jì)之魅:高質(zhì)量面向?qū)ο笤O(shè)計(jì)的秘密
網(wǎng)頁地址:http://www.dlmjj.cn/article/djepspd.html