设计模式笔记-----七大原则

一,设计模式的目的

提高代码重用性,可读性,可扩展性,可靠性,使程序具有低耦合高内聚的特征

二,七大原则

1.单一职责原则

2.接口隔离原则

3.依赖倒置原则

4.里欧替换原则

5.开闭原则

6.迪米特法则

7.合成复用原则

三,单一职责原则

1.一个类只负责一项职责

2.注意事项和细节

<1>降低类的复杂度,一个类只负责一个职责

<2>提高类的可读性,可维护性

<3>降低变更引起的风险

3.代码

<1>方案一

package 单一职责;

public class SingleResponsibility1 {
    public static void main(String []args){
        Vehicle vehicle=new Vehicle();
        vehicle.run("汽车");
        vehicle.run("飞机");
    }
}
//交通工具类
//方式一
//1.方式一的run方法中违反了单一职责原则
//2.解决方案:根据交通工具运行方法不同分解成不同的类即可
class Vehicle{
    public void run(String vehicle){
        System.out.println(vehicle+"在路上跑");
    }
}

<2>方案二

package 单一职责;

public class SingleResponseibility2 {
    public static void main(String []arg){
        new AirVehicle().run("飞机");
    }
}
//方案二
//遵守单一职责原则
//但是代码改动大
//可以直接改动Vehicle
class RoadVehicle{
    public void run(String name){
        System.out.println(name+"在公路上跑");
    }
}
class AirVehicle{
    public void run(String name){
        System.out.println(name+"在天上飞");
    }
}
class WaterVehicle{
    public void run(String name){
        System.out.println(name+"在水中游");
    }
}

<3>方案三

package 单一职责;

public class SingleResponsibility3 {
    public static void main(String[]args){

    }
}
//方式3
//没有对原来的类进行大的修改
//在方法上遵守了单一职责原则
//
class Vehicle2{
    public void run(String name){
        System.out.println(name+"在路上跑");
    }
    public void runAir(String name){
        System.out.println(name+"在天上飞");
    }
    public void runWater(String name){
        System.out.println(name+"在水中游");
    }
}

四,接口隔离原则

1.客户端不应该依赖他不需要的接口,即一个类对另一个类的依赖应该建立在最小接口上

2.代码实例

关系:类a通过接口1依赖于类b用到接口1中的1,2,3方法,类c通过接口1依赖类d会用到接口1中的1,4,5方法

<1>没有遵循接口隔离原则的代码

package 接口隔离;

public class Segeration1 {
    public static void main(String []args){
        
    }
}
interface Interface1{
    void operation1();
    void operation2();
    void operation3();
    void operation4();
    void operation5();
}
class B implements Interface1{
    @Override
    public void operation1() {
        System.out.println("B实现了方法1");
    }
    @Override
    public void operation2() {
        System.out.println("B实现了方法2");
    }
    @Override
    public void operation3() {
        System.out.println("B实现了方法3");
    }
    @Override
    public void operation4() {
        System.out.println("B实现了方法4");
    }
    @Override
    public void operation5() {
        System.out.println("B实现了方法5");
    }
}
class D implements Interface1{
    @Override
    public void operation1() {
        System.out.println("D实现了方法1");
    }
    @Override
    public void operation2() {
        System.out.println("D实现了方法2");
    }
    @Override
    public void operation3() {
        System.out.println("D实现了方法3");
    }
    @Override
    public void operation4() {
        System.out.println("D实现了方法4");
    }
    @Override
    public void operation5() {
        System.out.println("D实现了方法5");
    }
}
class A{
    public void Depend1(Interface1 i){
        i.operation1();
    }
    public void Depend2(Interface1 i){
        i.operation2();
    }
    public void Depend3(Interface1 i){
        i.operation3();
    }
}
class C{
    public void Depend1(Interface1 i){
        i.operation1();
    }
    public void Depend4(Interface1 i){
        i.operation4();
    }
    public void Depend5(Interface1 i){
        i.operation5();
    }
}

<2>遵循接口隔离原则的代码

package 接口隔离.改进;

public class Segeration {
}
interface Interface1{
    void operation1();
}
interface Interface2{
    void operation2();
    void operation3();
}
interface Interface3{
    void operation4();
    void operation5();
}
class B implements Interface1,Interface2{
    @Override
    public void operation1() {
        System.out.println("B实现了方法1");
    }

    @Override
    public void operation2() {
        System.out.println("B实现了方法2");
    }

    @Override
    public void operation3() {
        System.out.println("B实现了方法3");
    }
}
class D implements Interface1,Interface3{
    @Override
    public void operation1() {
        System.out.println("D实现了方法1");
    }

    @Override
    public void operation4() {
        System.out.println("D实现了方法4");
    }

    @Override
    public void operation5() {
        System.out.println("D实现了方法5");
    }
}
class A{
        public void Depend1(Interface1 i){
            i.operation1();
        }
        public void Depend2(Interface2 i){
            i.operation2();
        }
        public void Depend3(Interface2 i){
            i.operation3();
        }
}
class C{
    public void Depend1(Interface1 i){
        i.operation1();
    }
    public void Depend4(Interface3 i){
        i.operation4();
    }
    public void Depend5(Interface3 i){
        i.operation5();
    }
}

3.分析

<1>类a通过接口1依赖于类b,接口c用过接口1依赖于类d,由于接口1对于类a和类c不是最小接口,导致类 b和类d必须去实现他们不需要的方法

<2>将接口1拆分成三个接口,接口1只有方法1,接口2包含方法2,3.接口3包含方法4,5

<3>通过以上三个接口运用接口隔离原则即可

五,依赖倒转原则

1.高层模块不应该依赖底层模块,二者都应该依赖其抽象

2.抽象不应该依赖细节,细节应该依赖抽象

3.依赖倒转的中心思想是面向接口编程

4.设计理念:相对于细节的多变性,抽象的东西更加稳定,以抽象为基础搭建的架构比细节为基础的架构更加稳定

5.使用接口和抽象类的目的是制定好规范,而不涉及任何具体的细节,把展现细节的任务交给其具体实现类

6.代码

<1>未改进

package 依赖倒转;

public class Demo {
    public static void  main(String []args){
        new Person().get(new Email());
    }
}
//完成一个Person类接受消息
//方案一
//如果我们获取的对象是微信,短息,则需要新增加类,Person类也要增加响应的方法
class Email{
    public String getInfo(){
        return "电子邮件";
    }
}
class Person
{
    public void get(Email email){
        System.out.println(email.getInfo());
    }
}

<2>改进后

package 依赖倒转.改进;

public class Demochange {
    public static void main(String []args){
        Person person=new Person();
        person.get(new Email());
        person.get(new Wchat());
    }
}
interface Information{
    String getInfor();
}
class Email implements Information{
    @Override
    public String getInfor() {
        return "Email消息";
    }
}
class Wchat implements Information{
    @Override
    public String getInfor() {
        return "Wchat信息";
    }
}
class Person{
    public void get(Information information){
        System.out.println(information.getInfor());
    }
}

六,里氏替换

1.如果对每个类型为T1的对象O1,都有对于类型为T2的对象O2,使得定义的所有程序P在所有的对象O1替换成O2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型,也就是说,所有引用基类的地方必须能够透明的使用子类对象

2.在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类方法

3.里氏替换原则指出,继承实际上让两个类的耦合性增强了,在适当的情况下,可以通过耦合,组合,依赖来解决问题

4.代码

<1>未改进前

package 里氏替换;

public class Demo {
    public static void main(String []args){

    }
}
class A{
    int func1(int a,int b){
        return a-b;
    }
}
class B extends A{
    //重写了fun1方法,可能是无意识的
    int fun1(int a,int b){
        return a+b;
    }
    int fun2(int a,int b){
        return fun1(a,b)+9;
    }
}

*<2>改进后

package 里氏替换.改进;

import jdk.nashorn.internal.ir.BaseNode;

public class ImproveDemo {
    public static void main(String []args){

    }
}
class Base{
    int fun1(int a,int b){
        return a+b;
    }
}
class A extends Base{
    int fun1(int a,int b){
        return a-b;
    }
}
class B extends Base{
    int fun1(int a,int b){
        return new A().fun1(a,b);
    }
    int fun2(int a,int b){
        return fun1(a,b)+9;
    }
}

七,开闭原则

1.开闭原则是最基础最重要的原则

2.对扩展开放(针对功能提供方),对修改关闭(针对功能使用方),用抽象构建框架,用实现扩展细节

3.当软件需要变化时,尽量通过扩展软件实体的行为实现变化,而不是通过修改已有的代码实现变化

4.编程中遵循的其他原则以及使用设计模式的目的就是遵循开闭原则

5.代码

<1>完成绘制矩形和圆形的功能

package 开闭原则;

public class OcP {
    public static void main(String []args){

    }
}
class GraphicEditor{
    public void drawShape(Shape s){
        if(s.m_type==1){
            drawRectangle();
        }else if(s.m_type==2){
            drawCircle();
        }
    }
    public void drawRectangle(){
        System.out.println("绘制矩形");
    }
    public void drawCircle(){
        System.out.println("绘制圆形");
    }
}
class Shape{
    int m_type;
}
class Rectangle extends Shape{
    Rectangle(){
        super.m_type=1;
    }
}
class Circle extends Shape{
    Circle(){
        super.m_type=2;
    }
}

<2>在1中代码的基础上添加绘制三角形的功能

package 开闭原则;

public class Ocp2 {
    public static void main(String []args){
        System.out.println();
    }
}
class GraphicEditor1{
    public void drawShape(Shape s){
        if(s.m_type==1){
            drawRectangle();
        }else if(s.m_type==2){
            drawCircle();
        }else if(s.m_type==3){
            drawTriangle();
        }
    }
    public void drawRectangle(){
        System.out.println("绘制矩形");
    }
    public void drawCircle(){
        System.out.println("绘制圆形");
    }
    public void drawTriangle(){System.out.print("绘制三角形");}
}
class Shape1{
    int m_type;
}
class Rectangle1 extends Shape1{
    Rectangle1(){
        super.m_type=1;
    }
}
class Circle1 extends Shape1{
    Circle1(){
        super.m_type=2;
    }
}
class Triangle extends Shape1{
    Triangle(){super.m_type=3;}
}

从代码1到代码2,添加绘制三角形功能时,违背了开闭原则,因为对使用方GraphicEditor进行了更改

<3>对代码进行完善

定义抽象类Shape,在其中定义draw方法,让其他图形继承该抽象类,并实现自己的draw方法,在使用方会制图形时直接调用draw方法即可

package 开闭原则.improve;

public class OCP {
    public static void main(String []args) {

    }
}
class GraphicEditor{
    public static void drawShape(Shape shape){
        shape.draw();
    }
}
abstract class Shape{
    public abstract void draw();
}
class Rectangle extends Shape{
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}
class Triangle extends Shape{
    @Override
    public void draw() {
        System.out.println("绘制三角型");
    }
}
class Circle extends Shape{
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}
class OtherShape extends Shape{
    @Override
    public void draw() {
        System.out.println("绘制其他图形");
    }
}

八,迪米特法则

1.一个对象应该对其他对象保持最少的了解

2.类与类之间的关系越密切,耦合度越大

3.又称最少知道原则,即一个类对自己依赖的知道的越少越好

4.代码

打印学校员工和学院员工

<1>未改进

package 迪米特法则;

import javax.swing.event.ListDataEvent;
import java.util.ArrayList;
import java.util.List;

public class Demo {
    public static void main(String []args){
        SchoolManager schoolManager=new SchoolManager();
        schoolManager.printAllEmployee(new CollageManager());
    }
}
//学校员工
class Employee{
    private String id;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
}
//学院员工
class CollageEmployee{
    private String id;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
}
class CollageManager{
    //返回学院的所有员工
    public List<CollageEmployee> getAllCollageEmployee(){
        List<CollageEmployee>list=new ArrayList<>();
        for(int i=0;i<5;i++){
            CollageEmployee collageEmployee=new CollageEmployee();
            collageEmployee.setId("学院员工编号"+i);
            list.add(collageEmployee);
        }
        return list;
    }
}
class SchoolManager{
    public List<Employee> getAllEmployee(){
            List<Employee> list=new ArrayList<>();
            for(int i=0;i<5;i++){
                Employee employee=new Employee();
                employee.setId("学校员工编号"+i);
                list.add(employee);
            }
            return list;
    }
    public void printAllEmployee(CollageManager collageManager){
        List<CollageEmployee> list1=collageManager.getAllCollageEmployee();
        for(CollageEmployee i:list1){
            System.out.println(i.getId());
        }
        List<Employee> list2=this.getAllEmployee();
        System.out.println("==================================================");
        for(Employee i:list2){
            System.out.println(i.getId());
        }
    }
}

SchoolManeger与CollageEmployee在printAllEmployee方法种建立了依赖关系,实际上这种关系是没必要的,将输出学院员工的代码封装到CoolageManeger中即可

<2>改进后的代码

package 迪米特法则.Improve;

import javax.swing.event.ListDataEvent;
import java.util.ArrayList;
import java.util.List;

public class Demo {
    public static void main(String []args){
        SchoolManager schoolManager=new SchoolManager();
        schoolManager.printAllEmployee(new CollageManager());
    }
}
//学校员工
class Employee{
    private String id;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
}
//学院员工
class CollageEmployee{
    private String id;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
}
class CollageManager{
    //返回学院的所有员工
    public List<CollageEmployee> getAllCollageEmployee(){
        List<CollageEmployee>list=new ArrayList<>();
        for(int i=0;i<5;i++){
            CollageEmployee collageEmployee=new CollageEmployee();
            collageEmployee.setId("学院员工编号"+i);
            list.add(collageEmployee);
        }
        return list;
    }
    public void printAllCollageEmployee(){
        List<CollageEmployee> list1=this.getAllCollageEmployee();
        for(CollageEmployee i:list1){
            System.out.println(i.getId());
        }
    }
}
class SchoolManager{
    public List<Employee> getAllEmployee(){
        List<Employee> list=new ArrayList<>();
        for(int i=0;i<5;i++){
            Employee employee=new Employee();
            employee.setId("学校员工编号"+i);
            list.add(employee);
        }
        return list;
    }
    public void printAllEmployee(CollageManager collageManager){
        collageManager.printAllCollageEmployee();
        List<Employee> list2=this.getAllEmployee();
        System.out.println("==================================================");
        for(Employee i:list2){
            System.out.println(i.getId());
        }
    }
}

九,合成复用法则
1.尽量使用合成聚合的方式,而不是使用继承

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值