Java软件设计原则

 

先了解UML相关知识

UML类图

+ 表示public

- 表示privae

# 表示protected

~ 表示defualt

下划线 表示static

斜体 表示abstract

 

开闭原则:对扩展开放,对修改闭合。

// 1.首先创建一个接口ICourse
public interface ICourse {
    Integer getid();
    String getName();
    Double getPrice();
}


// 2.该接口的实现类
public class JavaCourse implements ICourse {
    Integer mId;
    String mName;
    Double mPrice;

    public JavaCourse(Integer id, String name, Double price) {
        this.mId = id;
        this.mName = name;
        this.mPrice = price;
    }

    @Override
    public Integer getid() {
        return mId;
    }

    @Override
    public String getName() {
        return mName;
    }

    @Override
    public Double getPrice() {
        return mPrice;
    }
}

// 3.调用实现类
ICourse javaCourse= new JavaCourse(98,"Java入门课程",288d);
        String r="id="+javaCourse.getid()+";name="+javaCourse.getName()+";原价="+javaCourse.getPrice();
        System.out.println(r);

// 4.输出结果
id=98;name=Java入门;原价=288.0


上面是基本操作,现在假设有这么个需求,过节做活动,课程打折,八折,怎么实现?那不是很简单,直接将实现类里面的方法改一下,原价*0.8:

public Double getPrice() {
        return mPrice * 0.8;
    }

这确实达到了要求,但是如果还要显示原价呢,原价是多少,如果把打八折后的结果除以0.8得到原价,那也太麻烦了。再考虑一下,如果还有其他类实现了JavaCourse类,现在修改了JavaCourse类的getPrice方法,那么其子类全部都改了,还不知道有多大的影响。有人说,我的类少,我可以改,吭哧吭哧改一下,也能实现。是的,没错,但是如果现在有开闭原则,能使代码更优雅,方便你我他,何乐不为呢。

//新建一个类,继承JavaCourse类,并且增加一个方法getDiscountPrice获取折后价
public class JavaDiscountCourse extends JavaCourse {
    public JavaDiscountCourse(Integer mId, String mName, Double mPrice) {
        super(mId, mName, mPrice);
    }

    public Double getDiscountPrice(){
        return super.getPrice()*0.8;
    }
}


//调用
ICourse iCourse= new JavaDiscountCourse(98,"Java入门",288d);
        JavaDiscountCourse javaCourse= (JavaDiscountCourse) iCourse;
        String r="id="+javaCourse.getid()+";name="+javaCourse.getName()+";原价="+javaCourse.getPrice()
                +";折后价:"+javaCourse.getDiscountPrice();
        System.out.println(r);

//输出结果
id=98;name=Java入门;原价=288.0;折后价:230.4

  这样通过修改实现继承子类(对扩展开放),不修改基类或接口(对修改闭合)来符合开闭原则。

上面这张图是UML的类图,在Android studio安装SimpleUMLCE插件,重启后右击文件夹,生成类图。

 

依赖倒置原则

//新建一个类
public class StudyCourse {
    public void studyJavaCourse(){
        System.out.println("学习JAVA课程");
    }

    public void studyAndroidCourse(){
        System.out.println("学习Android课程");
    }
}

//调用
    StudyCourse studyCourse=new StudyCourse();
    studyCourse.studyJavaCourse();
    studyCourse.studyAndroidCourse();

//输出结果
学习JAVA课程
学习Android课程

那么问题来了,现在如果想添加一个“学习iOS"的方法,直接在StudyCourse类里添加方法的话,这就是面向实现编程。那么此实现类会经常修改,扩展性较差。 下面看看依赖倒置原则下的实现。

 

//新建一个接口
public interface ICourse {
    void studyCourse();
}

//实现该接口的类
public class StudyJavaCourse implements ICourse{

    @Override
    public void studyCourse() {
        System.out.println("学习JAVA课程");
    }
}

//实现该接口的类
public class StudyAndroidCourse  implements ICourse {
    @Override
    public void studyCourse() {
        System.out.println("学习Android课程");
    }
}


public class StudyCourse {
    public void studyMyCourse(ICourse iCourse){
        iCourse.studyCourse();
    }
}

//调用
 StudyCourse studyCourse=new StudyCourse();
        studyCourse.studyMyCourse(new StudyJavaCourse());
        studyCourse.studyMyCourse(new StudyAndroidCourse());

//结果
学习JAVA课程
学习Android课程

上面的实现看起来麻烦很多,多写了很多代码,那这样带来的好处是什么呢?如果想添加一个“学习iOS"的方法,新建一个类实现ICourse接口里面的方法,这样面向接口编程,而不是面向实现类StudyCourse编程。StudyCourse类与StudyJavaCourse实现类解耦,StudyCourse类与接口ICourse耦合。依赖倒置原则的核心就是面向抽象(抽象类或者接口)编程。

 

单一职责原则

//新建一个类Bird
public class Bird {
    public void move(String name){
        if ("鸵鸟".equals(name)){
            System.out.println(name+"用脚走");
        }
        else {
            System.out.println(name+"用翅膀飞");
        }
    }
}

//调用
    Bird bird=new Bird();
    bird.move("大雁");
    bird.move("鸵鸟");

//结果
大雁用翅膀飞
鸵鸟用脚走

现在如果要添加其他鸟类,继续加 if 判断,如果判断的逻辑复杂,很容易出错。下面试试单一职责原则。

//新建一个类
public class FlyBird {
    public void move(String name){
        System.out.println(name+"用翅膀飞");
    }
}

//新建一个类
public class WalkBird {
    public void move(String name){
        System.out.println(name+"用脚走");
    }
}

//调用
FlyBird flyBird=new FlyBird();
        flyBird.move("大雁");

        WalkBird walkBird=new WalkBird();
        walkBird.move("鸵鸟");

//结果
大雁用翅膀飞
鸵鸟用脚走

对于类而言,使用单一职责原则,可能导致类的爆炸,可以酌情使用。反而对于方法而言,尽量使用单一职责原则。

接口隔离原则

//新建一个接口,声明三个方法
public interface IAnimalAction {
    void eat();
    void fly();
    void swim();
}

//新建实现类,实现该接口
public class Dog implements IAnimalAction {
    @Override
    public void eat() {
    }

    @Override
    public void fly() {
    }

    @Override
    public void swim() {
    }
}

//新建实现类,实现该接口
public class Bird implements IAnimalAction {
    @Override
    public void eat() {
    }

    @Override
    public void fly() {
    }

    @Override
    public void swim() {
    }
}

实现类Dog有eat方法,有swim方法,但是没有fly方法。实现类Bird有eat方法,不一定有fly方法,不一定有swim方法。下面是接口隔离原则的实现。

//新建接口
public interface IEatAction {
    void eat();
}

//新建接口
public interface IFlyAction {
    void fly();
}

//新建接口
public interface ISwimAction {
    void swim();
}

//Dog类有eat方法,有swim方法,因此只实现IEatAction,ISwimAction这两接口
public class Dog implements IEatAction,ISwimAction {
    @Override
    public void eat() {
    }

    @Override
    public void swim() {
    }
}

//Bird只有eat方法,只实现IEatAction接口。
public class Bird implements IEatAction {
    @Override
    public void eat() {
    }
}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值