连载:面向对象葵花宝典:思想、技巧与实践(39) - 设计原则 vs 设计模式

简介:

又是设计原则,又是设计模式,到底该用哪个呢? =============================================================================

在“设计模型”一章中,我们提到设计原则和设计模式是互补的,设计原则和设计模式互补体现在:设计原则主要用于指导“类的定义”的设计,而设计模式主要用于指导“类的行为”的设计。

 

举一个很简单的例子:假设我们要设计一个图形类Shape,这个类既支持三角形,又支持矩形,其代码如下:

package com.oo.designpattern.diagram;

/**
 * 设计不好的Shape类,同时兼顾三角形和矩形的职责,不符合SRP设计原则
 *
 */
public class BadShape {

    //三角形的属性
    Position a;
    Position b;
    Position c;
    
    //矩形的属性
    Position m;
    int length;
    int width;
    
    public void drawTriangle(){
        //TODO: 画出三角形
    }
    
    public void drawRectangle(){
        //TODO: 画出矩形
    }
}


有经验的朋友都会觉得这个设计不太合理,因为其不符合类的SRP设计原则。因此,合理的做法是将这个类按照SRP原则拆分,具体拆分方法如下:

NormalShape.java

package com.oo.designpattern.diagram;

/**
 * 将BadShape拆开为三角形和矩形两个图形,并提取出NormalShape这个父类
 *
 */
abstract class NormalShape {
    abstract void draw();
}

NormalTriangle.java

package com.oo.designpattern.diagram;

/**
 * 三角形类
 *
 */
public class NormalTriangle extends NormalShape {
   
    //三角形的属性
    Position a;
    Position b;
    Position c;
    
    @Override
    public void draw() {
        // TODO:绘画三角形
        if(Config.CURRENT_SYSTEM == Config.WINDOWS){
            //TODO: 调用Windows的画图方法
        }
        else if( Config.CURRENT_SYSTEM == Config.LINUX){
            //TODO: 调用Linux的画图方法
        }
        else if( Config.CURRENT_SYSTEM == Config.MAC){
            //TODO: 调用Mac的画图方法
        }
    }

}

NormalRectangle.java

package com.oo.designpattern.diagram;

/**
 * 矩形类
 *
 */
public class NormalRectangle extends NormalShape {

    //矩形的属性
    Position m;
    int length;
    int width;
    
    @Override
    public void draw() {
        // TODO: 绘画矩形
        if(Config.CURRENT_SYSTEM == Config.WINDOWS){
            //TODO: 调用Windows的画图方法
        }
        else if( Config.CURRENT_SYSTEM == Config.LINUX){
            //TODO: 调用Linux的画图方法
        }
        else if( Config.CURRENT_SYSTEM == Config.MAC){
            //TODO: 调用Mac的画图方法
        }
    }

}


这样拆分之后,从类的设计原则来看,已经是符合要求了。

 

接下来我们再使用设计模式来继续完善这个设计,这里就需要使用设计模式之道来指导我们设计了,即:找到变化,封装变化

 

关于图形类一个比较明显的变化是跨平台,比如说要同时支持Windows、Linux、Mac三个桌面操作系统,那么实际画图的方法和需要调用的函数可能就随着平台的不同而变化,因此我们要找出一种方法来封装这种变化。

 

参考《设计模式》,可以知道这种方法就是“Bridge模式”,使用了Bridge后,会多出几个接口和实现类。

具体实现如下:

GoodShape.java

package com.oo.designpattern.diagram;

/**
 * 在NormalShape的基础上,增加Bridge设计模式的实现,使其更加适应于跨平台
 *
 */
abstract public class GoodShape {

    protected ShapeDraw _draw;  //将不同平台的实现封装到一个新的接口ShapeDraw
    abstract void draw();
}


GoodTriangle.java

package com.oo.designpattern.diagram;

/**
 * 按照Bridge设计模式设计的三角形类
 *
 */
public class GoodTriangle extends GoodShape {

    GoodTriangle(ShapeDraw draw){
        this._draw = draw;
    }
    
    @Override
    void draw() {
        // TODO Auto-generated method stub
        this._draw.drawTriangle();
    }

}

GoodRectangle.java

package com.oo.designpattern.diagram;

/**
 * 按照Bridge设计模式设计的矩形类
 *
 */
public class GoodRectangle extends GoodShape {

    GoodRectangle(ShapeDraw draw){
        this._draw = draw; 
    }
    
    @Override
    void draw() {
        // TODO Auto-generated method stub
        this._draw.drawRectangle();
    }

}

ShapeDraw.java

package com.oo.designpattern.diagram;

/**
 * 按照Bridge设计模式进行设计的画图的接口,封装了跨平台不同的实现
 *
 */
interface ShapeDraw {

    public void drawTriangle();
    public void drawRectangle();
}

WindowsDraw.java

package com.oo.designpattern.diagram;

/**
 * Windwos上的画图实现
 *
 */
public class WindowsDraw implements ShapeDraw {

    @Override
    public void drawTriangle() {
        // TODO Auto-generated method stub

    }

    @Override
    public void drawRectangle() {
        // TODO Auto-generated method stub

    }

}

LinuxDraw.java

package com.oo.designpattern.diagram;

/**
 * Linux上的画图实现
 *
 */
public class LinuxDraw implements ShapeDraw {

    @Override
    public void drawTriangle() {
        // TODO Auto-generated method stub

    }

    @Override
    public void drawRectangle() {
        // TODO Auto-generated method stub

    }

}

MacDraw.java

package com.oo.designpattern.diagram;

/**
 * Mac上的画图实现
 *
 */
public class MacDraw implements ShapeDraw {

    @Override
    public void drawTriangle() {
        // TODO Auto-generated method stub

    }

    @Override
    public void drawRectangle() {
        // TODO Auto-generated method stub

    }

}

可以看到,按照设计原则和设计模式进行重构后,原来不合理的设计逐步演变为一个优秀的设计了


================================================ 
转载请注明出处:http://blog.csdn.net/yunhua_lee/article/details/38655873
================================================ 

相关文章
|
1月前
|
设计模式 算法 搜索推荐
后端开发中的设计模式应用与实践
在软件开发的广袤天地中,后端技术如同构筑高楼大厦的钢筋水泥,支撑起整个应用程序的骨架。本文旨在通过深入浅出的方式,探讨后端开发领域内不可或缺的设计模式,这些模式犹如精雕细琢的工具箱,能够助力开发者打造出既健壮又灵活的系统架构。从单例模式到工厂模式,从观察者模式到策略模式,每一种设计模式都蕴含着深刻的哲理与实践价值,它们不仅仅是代码的组织方式,更是解决复杂问题的智慧结晶。
|
2月前
|
设计模式 算法 测试技术
PHP中的设计模式:策略模式的应用与实践
在软件开发的浩瀚海洋中,设计模式如同灯塔,指引着开发者们避开重复造轮子的暗礁,驶向高效、可维护的代码彼岸。今天,我们将聚焦于PHP领域中的一种重要设计模式——策略模式,探讨其原理、应用及最佳实践,揭示如何通过策略模式赋予PHP应用灵活多变的业务逻辑处理能力,让代码之美在策略的变换中熠熠生辉。
|
22天前
|
设计模式 API 持续交付
深入理解微服务架构:设计模式与实践
【10月更文挑战第19天】介绍了微服务架构的核心概念、设计模式及最佳实践。文章详细探讨了微服务的独立性、轻量级通信和业务能力,并介绍了聚合器、链式和发布/订阅等设计模式。同时,文章还分享了实施微服务的最佳实践,如定义清晰的服务边界、使用API网关和服务发现机制,以及面临的挑战和职业心得。
|
1月前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入解析与实践
在PHP开发中,设计模式是提高代码可维护性、扩展性和复用性的关键技术之一。本文将通过探讨单例模式,一种最常用的设计模式,来揭示其在PHP中的应用及优势。单例模式确保一个类仅有一个实例,并提供一个全局访问点。通过实际案例,我们将展示如何在PHP项目中有效实现单例模式,以及如何利用这一模式优化资源配置和管理。无论是PHP初学者还是经验丰富的开发者,都能从本文中获得有价值的见解和技巧,进而提升自己的编程实践。
|
1月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第9天】 策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在PHP开发中,通过使用策略模式,我们可以轻松切换算法或逻辑处理方式而无需修改现有代码结构。本文将深入探讨策略模式的定义、结构以及如何在PHP中实现该模式,并通过实际案例展示其应用价值和优势。
28 1
|
1月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
在PHP开发中,设计模式是提高代码可读性、可维护性和扩展性的重要工具。本文将深入探讨策略模式这一行为型设计模式,通过分析其定义、结构、使用场景以及在PHP中的实际应用,帮助开发者更好地理解和运用策略模式来优化自己的项目。不同于传统摘要的简洁概述,本文摘要部分将详细阐述策略模式的核心理念和在PHP中的实现方法,为读者提供清晰的指引。
|
1月前
|
设计模式 存储 测试技术
PHP中的设计模式:单例模式的深入解析与实践
在PHP开发领域,设计模式是解决常见问题的最佳实践。本文将深入探讨单例模式,一种确保类只有一个实例的设计模式,并提供实际应用示例。我们将从单例模式的基本概念讲起,通过实际案例展示如何在PHP中实现单例模式,以及它在不同场景下的应用和优势。最后,我们会探讨单例模式的优缺点,帮助开发者在实际项目中做出明智的选择。
|
1月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
策略模式是一种行为型设计模式,用于定义一系列算法,将每种算法都封装起来,并使它们可以互换。本文将探讨如何在PHP中实现策略模式,以及如何利用它来提高代码的灵活性和可维护性。通过具体示例,我们将看到策略模式在处理复杂业务逻辑时的优势,从而帮助开发者编写出更加清晰、易于扩展的代码。
|
1月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。
|
1月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
在软件开发的广袤领域中,PHP以其灵活性和广泛的应用场景占据了一席之地。本文聚焦于PHP中的一个核心概念——设计模式,特别是策略模式。策略模式作为一种行为型设计模式,允许在运行时选择算法或操作的具体实现,为软件设计带来了极大的灵活性。本文将深入探讨策略模式的基本原理、应用场景以及在PHP中的具体实现方式,旨在帮助开发者更好地理解和运用这一设计模式,提升代码的可维护性和扩展性。
18 2