zoukankan      html  css  js  c++  java
  • 连载:面向对象的葵花宝典:思考、技巧与实践(39)

    它的设计原则,和设计模式,是否该用它? =============================================================================

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

     

    举一个非常easy的样例:如果我们要设计一个图形类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
    ================================================ 

    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    多线程
    JavaSE
    SpringBoot是什么,可以做什么?
    SSM框架中如何简便上传文件表单
    SQL语句全解,非常棒!
    关于HttpSession 和 Hibernate框架中 session异同点的简单解析
    关于Javascript中页面动态钟表的简单实现
    Java 面向对象 知识点基础浅谈
    Eclipse无法正常启动,弹出对话框内容为 A Java Runtime...
    关于Java中面向对象章节、IO 流中的重点基础知识。
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4822084.html
Copyright © 2011-2022 走看看