模式模式(一)

设计模式

课程链接: bilibili尚硅谷课程

  • 设计模式的七大原则
    • 单一职责原则
    • 接口分离原则
    • 依赖反转原则
    • 里氏替换原则
    • 开闭原则
    • 迪米特法则
    • 合成复用原则

1 单一职责原则

顾名思义:一个类只应该对一项负责

public class Singleresponsibility {
    public static void main(String[] args) {
        Vehicle vehicle = new Vehicle();
        //违反了单一原则的原则
        vehicle.run("摩托车");
        vehicle.run("汽车");
        vehicle.run("飞机");
    }

}


class Vehicle {
    public void run(String vehicle){
        System.out.println(vehicle + " 在公路上跑");
    }

}

上述代码Vehicle类一个类承担了所有交通工具run的功能,并不是合理的设计,需要对其进行分离。

public class Singleresponsibility2 {
    public static void main(String[] args) {
        RoadVehicle roadVehicle = new RoadVehicle();
        roadVehicle.run("摩托车");
        roadVehicle.run("汽车");

        WaterVehicle waterVehicle = new WaterVehicle();
        waterVehicle.run("船");

        AirVehicle airVehicle = new AirVehicle();
        airVehicle.run("飞机");
    }
}

class AirVehicle {
    public void run(String vehicle) {
        System.out.println(vehicle + " 在天空运行");
    }
}

class RoadVehicle {

    public void run(String vehicle) {
        System.out.println(vehicle + "在路上运行");
    }
}

class WaterVehicle {
    public void run(String vehicle){
        System.out.println(vehicle + "在水中运行");
    }
}

上述代码做到了单一原则,一个类负责各自的领域,但是改动太大了

public class Singleresponsibility3 {
    public static void main(String[] args) {
        Vehicle2 vehicle2 = new Vehicle2();
        vehicle2.run("汽车");
        vehicle2.runWater("轮船");
        vehicle2.runAir("飞机");
    }
}

// 方式3的分析
// 1. 未对原来的类做大的修改,只是增加方法
// 2. 在类的级别上未遵守单一职责,但在方法的级别上遵守了单一职责
class Vehicle2 {
    public void run(String vehicle){
        System.out.println(vehicle + " 在公路上运行");
    }
    public void runAir(String vehicle){
        System.out.println(vehicle + " 在天空中运行");
    }

    public void runWater(String vehicle){
        System.out.println(vehicle + " 在水中运行");
    }

}

老师介绍了上面三种改进的方法,如果让我设计会设计成如下方案:

public class Singleresponsibility4 {
    public static void main(String[] args) {
        VehcileWays vehcileWays = new VehcileWays();
        vehcileWays.show(new Car());
        vehcileWays.show(new Plane());
        vehcileWays.show(new Boat());
    }
}

interface Vehicles{
    void run();
}


class Car implements Vehicles{

    private String name;
    @Override
    public void run() {
        System.out.println("汽车在公路上运行");
    }
}

class Boat implements Vehicles{

    @Override
    public void run() {
        System.out.println("船在水上运行");
    }
}

class Plane implements Vehicles{

    @Override
    public void run() {
        System.out.println("飞机在空中运行");
    }
}

class VehcileWays{
    public void show(Vehicles vehicles){
        vehicles.run();
    }
}

命名方式有待商榷


2 接口隔离原则

让接口负责的内容尽可能小,大接口拆分为小接口,避免接口浪费

  • 原来的大接口模式

    package com.qxd.principle;
    
    public class Segregation {
        public static void main(String[] args) {
    
        }
    }
    
    interface Interface1{
        void operation1();
        void operation2();
        void operation3();
        void operation4();
        void operation5();
    }
    
    
    class B implements Interface1 {
        public void operation1() {
        System.out.println("B 实现了 operation1");
        }
        public void operation2() {
            System.out.println("B 实现了 operation2");
        }
        public void operation3() {
            System.out.println("B 实现了 operation3");
        }
        public void operation4() {
            System.out.println("B 实现了 operation4");
        }
        public void operation5() {
            System.out.println("B 实现了 operation5");
        }
    }
    
    class D implements Interface1 {
        public void operation1() {
            System.out.println("D 实现了 operation1");
        }
    
    
        public void operation2() {
            System.out.println("D 实现了 operation2");
        }
    
        public void operation3() {
            System.out.println("D 实现了 operation3");
        }
    
        public void operation4() {
            System.out.println("D 实现了  operation4");
        }
    
        public void  operation5()  {
            System.out.println("D 实现了  operation5");
        }
    }
    
    
    class A { //A 类通过接口 Interface1 依赖(使用) B 类,但是只会用到 1,2,3 方法
        public void depend1(Interface1 i) {
            i.operation1();
        }
    
        public void depend2(Interface1 i) {
            i.operation2();
        }
    
        public void depend3(Interface1 i) {
            i.operation3();
        }
    }
    
    class C { //C 类通过接口 Interface1  依赖(使用) D 类,但是只会用到 1,4,5 方法
        public void depend1(Interface1 i) { i.operation1();
        }
        public void depend4(Interface1 i) { i.operation4();
        }
        public void depend5(Interface1 i) { i.operation5();
        }
    }
    

    class A 与class B通过接口Interface1发生关系,Interface1就是缓冲层,避免两者发生直接的碰撞,A只要调用B的1,2,3方法,但是B实现了接口的所有方法,说明这个接口太大了,需要瘦身。

    package com.qxd.principle.improve;
    
    public class Segregation1 {
        public static void main(String[] args) {
            A a = new A();
            a.depend1(new B()); // A 类通过接口去依赖 B 类
            a.depend2(new B());
            a.depend3(new B());
    
            C c = new C();
            c.depend1(new D()); // C 类通过接口去依赖(使用)D 类
            c.depend4(new D());
            c.depend5(new D());
        }
    }
    
    // 接 口 1
    interface Interface1 {
        void operation1();
    }
    
    
    // 接 口 2
    interface Interface2 {
        void operation2();
        void operation3();
    }
    
    // 接 口 3
    interface Interface3 {
        void operation4();
        void operation5();
    }
    
    class B implements Interface1, Interface2 {
        public void operation1() {
            System.out.println("B 实现了 operation1");
        }
    
    
        public void operation2() {
            System.out.println("B 实现了 operation2");
        }
    
    
        public void operation3() {
            System.out.println("B 实现了 operation3");
        }
    }
    
    class D implements Interface1, Interface3 {
        public void operation1() {
            System.out.println("D 实现了  operation1");
        }
    
    
        public void operation4() {
            System.out.println("D 实现了  operation4");
        }
    
    
        public void operation5() {
            System.out.println("D 实现了 operation5");
        }
    }
    
    
    class A { // A 类通过接口 Interface1,Interface2 依赖(使用) B 类,但是只会用到 1,2,3 方法
        public void depend1(Interface1 i) {
            i.operation1();
        }
    
    
        public void depend2(Interface2 i) {
            i.operation2();
        }
    
    
        public void depend3(Interface2 i) {
            i.operation3();
        }
    }
    
    
    
    class C { // C  类通过接口 Interface1,Interface3  依赖(使用) D 类,但是只会用到 1,4,5 方法
        public void depend1(Interface1 i) {
            i.operation1();
        }
    
    
        public void depend4(Interface3 i) {
            i.operation4();
        }
    
    
        public void depend5(Interface3 i) {
            i.operation5();
        }
    }
    

    接口的设计也需要“求同存异”


3 依赖倒转原则

本质就是面向接口编程

比如 class A中的某个方法形参为class B ,那么以后传入的参数就只能是class B了, 拓展性差。

但是class A中某个方法形参为class B抽象的接口的话,那么传入的参数就是该接口的实现类,易于维护。

package com.qxd.principle.inversion;

public class DependyInversion{
    public static void main(String[] args) {
        Person person = new Person();
        person.receive(new Email());
    }
}

class Email {
    public String getInfo() {
        return "电子邮件信息: hello,world";
    }
}


class Person {
    public void receive(Email email ) {
        System.out.println(email.getInfo());
    }
}

*****************************************************************************************************
    public class DependyInversion{
    public static void main(String[] args) {
        //客户端无需改变
        Person person = new Person();
        person.receive(new Email());
        person.receive(new WeiXin());
    }
}

//定义接口
interface IReceiver {
    public String getInfo();
}


class Email implements IReceiver{
    public String getInfo() {
        return "电子邮件信息: hello,world";
    }
}

//增加微信
class WeiXin implements IReceiver {
    public String getInfo() {
    return "微信信息: hello,ok";
}

}
class Person {
    public void receive(IReceiver iReceiver ) {
        System.out.println(iReceiver.getInfo());
    }
}

上述两端代码对比即可发现两者的差距

  • 依赖关系传递的三种方式和应用案例

    • 接口传递
    //打开或者关闭哪个电视
    interface IOpenAndClose {
        public void open(ITV tv); //抽象方法,接收接口
    
    }
    
    interface ITV { //ITV 接口
        public void play();
    }
    // 实现接口
     class OpenAndClose implements IOpenAndClose{
        public void open(ITV tv){
            tv.play();
        }
     }
    
    • 构造方法传递应用案例代码
    class OpenAndClose2 {
        public ITV tv; //成员
    
        public OpenAndClose2(ITV tv) { //构造器
            this.tv = tv;
        }
    
        public void open() {
            this.tv.play();
        }
    }
    
    • setter 方式传递

      上述代码构造器传值改为set传值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值