类设计-开闭、单一、里氏替换、依赖倒置、接口隔离、迪米特原则

  1. 某图形界面系统提供了各种不同形状的按钮,客户端代码科针对这些按钮进行编程,用户可能会改变要求使用不同的按钮,原始设计如图1所示。 类设计-开闭、单一、里氏替换、依赖倒置、接口隔离、迪米特原则_第1张图片
    画出利用开闭原则重构后的类图。

结合题目分析这个类图,题目中说到“用户可能会改变要求使用不同的按钮”,而且要求我们利用开闭原则画出重构后的类图。

开闭原则:可以增加按钮,但是不能修改原来的代码。

我们都知道抽象比较稳定,所以这里使用抽象,那用接口还是抽象类呢?我的选择是抽象类,因为这里需要抽象的是按钮,抽象的物,不是按钮的操作,所以我们选择抽象类。

public abstract class AbstractButton{
    public abstract void view();
}

public class CircleButton extends AbstractButton{
    public void view(){}
}

public class RactangleButton extends AbstractButton{
    public void view(){}
}

public class UserForm{
    pirvate AbstractButton button;
    public void setAbstractButton(AbstractButton b){
       this.button = b;
    }
    public void display(){
       button.view(){}
    }
}

类设计-开闭、单一、里氏替换、依赖倒置、接口隔离、迪米特原则_第2张图片

  1. 某基于Java的C/S系统的“登陆功能”通过如图2登陆类Login实现。请使用单一职责原则对其进行重构。 类设计-开闭、单一、里氏替换、依赖倒置、接口隔离、迪米特原则_第3张图片

一看到这个类图我们就想,这个类图功能真强大,啥都能干。但是考虑一下复用性,简直没有复用性可言。

单一原则修改后:

public class Test{
    public statci void main(String[] args){
    }
}

public class LoginForm{
    private UserDao userDao;
    public void setUserDao(UserDao dao){this.userDao = dao}
    public void init(){}
    public void display(){}
    public booleanlogin(){}
    public void volidate(){}
}

public class UserDao{
    private DBUtil dbUtil;
    public void setDBUtil(DBUtil db){this.dbUtil = db}
    public boolean findUser(String userName,String userPassword){}
}

public class DBUtil{
    public Connection getConnection(){}
}

类设计-开闭、单一、里氏替换、依赖倒置、接口隔离、迪米特原则_第4张图片

  1. 某系统需要实现对重要数据的加密处理,在数据操作类中需要调用加密类中定义的加密算法,系统提供了两个不同的加密类,CipherA和CipherB,他们实现不同的加密方法,在数据操作类可以选择其中的一个实现加密操作。初始设计如图3所示。请利用里氏替换原则对图3的模型进行重构。

类设计-开闭、单一、里氏替换、依赖倒置、接口隔离、迪米特原则_第5张图片

里氏替换原则:用于做同一件事,用不同方法。不仅要合乎语法还要合乎逻辑。这件事父类(基类)定义的,如果基类能做,那么子类也肯定能做。

public class Cilent{
    public satatic void main(String[] args){
        DataOperator dataOperator = new DataOperator();
        dataOperator.setCipherA(new CipherB());    //采用子类的加密方法
        String text = dataOperator.encode(String plainTest);
    }
}

public class DataOperator{
    private CipherA cipherA;
    public void setCipherA(CipherA ca){this.cipherA = ca};
    public String void encode(String plainText){
        cipherA.encode(plainText);
    }
}

public class CipherA{
    public String encode(String plainText){}
}

public class CipherB extends CipherA{
    public String encode(String plainText){}
}

类设计-开闭、单一、里氏替换、依赖倒置、接口隔离、迪米特原则_第6张图片

  1. 某系统需要定义Cone类和其底面类Triangle,其底面的类型后期可能会变化。初始的设计如图4所示,请利用依赖倒置原则对图4的模型进行重构。

类设计-开闭、单一、里氏替换、依赖倒置、接口隔离、迪米特原则_第7张图片

分析这题我们知道,我们想要求锥体的面积,但是它依赖于底面积,并且底面积还会变。会变的东西我们把它抽象,使用接口还是抽象类呢。似乎接口和抽象类都可以,我选择抽象级别跟高的接口。

 public class Test{      
            public static void main(String[] args){
                    TriangleCone cone= new TriangleCone();          
                    cone.setButton(new Triangle());        //底面积为长方形
                    double volume =  cone.volunm(cone.button.area(),getH(2));             
             }
}

public class TriangleCone{
        private int h;
    ​    ​private ButtonShape button;
        public void setH(int high){this.h = high}
    ​    ​public void getH(){return h;}
    ​    ​public void setButton(ButtonShape b){this button = b}
    ​    ​public double volunm(button.area(),h){}
}

public interface ButtonShape{
    ​    ​public double area();
}

public class Triangle implements ButtonShape{public int a,b,c;public double area(){}
}

public class Circle implements ButtonShape{
    public int radius;
    public double area(){}
}

类设计-开闭、单一、里氏替换、依赖倒置、接口隔离、迪米特原则_第8张图片

  1. 开发人员针对某个CRM系统的客户数据显示模块设计了下面的接口。其中dataRead()用于从文件中读取数据,transformToXML()用于将数据转换为XML格式,方法createChart()用于创建图表,displayChart()用于显示图表,createReport()用于创建文字报表,displayReport()用于显示文字报表。初始设计如图5所示。请利用接口隔离原则对图5模型进行重构。
    类设计-开闭、单一、里氏替换、依赖倒置、接口隔离、迪米特原则_第9张图片

接口隔离原则:注重的是抽象和接口。用于避免“胖接口”,把“胖”接口分为更小更内聚的接口。

分析:文件中读取数据是必须的,所以定义为父接口,每一个小接口都要继承父接口。我想生成报表我就实现报表接口就行了。

public interface CustomerData{public void dataRead();
}

public interface CustomerDataDisplay extends CustomerData{public void createChart();public void displayChart();
}

public interface CustomerDataReport extends CustomerData{public void createReport();public void displayReport();
}

public interface CustomerDataTrans extends CustomerData{public void transformXML();
}

public class ConcreteClass implements CustomerDataDisplay{public void dataRead(){}public void createChart(){}public void displayChart(){}
}

public class ClientCRM{public static void main(String[] args){
    ​    ​    ​ConcreteClass chart = new ConcreteClass();//图表实现类
    ​    ​    ​chart.dataRead();
    ​    ​    ​chart.createChart();
    ​    ​    ​chart.displayChart();}
}

类设计-开闭、单一、里氏替换、依赖倒置、接口隔离、迪米特原则_第10张图片

5、迪米特原则

小总结:

  1. 开闭原则:利用抽象的稳定性来实现增加开,修改闭。
  2. 单一原则:高内聚。
  3. 里氏替换原则:语法和逻辑都满足的情况下用不同方法做同一件事。子类继承基类。用业务类来屏蔽多态性。
  4. 依赖替换原则:高模块不依赖于低模块,二者都依赖抽象依赖抽象;面向接口编程。可用来高低模块同时开发。
  5. 接口隔离原则:避免“胖”接口,通过角色来分为小接口,实现高内聚,提高灵活性。将每个小接口都要做的事情抽象为父接口,小接口为子接口。
  6. 迪米特原则:低耦合;让每个类 依赖、关联、聚合、组合、泛化、实现 的类尽可能少。

你可能感兴趣的:(JAVA)