简述设计模式——概括

为什么要学习设计模式

  1. 设计模式已经成为软件开发人员的“标准词汇”
  2. 学习设计模式是个人技术能力提高的捷径
  3. 不用重复造轮子

学习设计模式的层次

  1. 基本入门级
  2. 基本掌握级
  3. 深入理解和掌握级

常见的面向对象设计原则

1、单一职责SRP(Single Responsibility Principle)

所谓单一职责原则,指的是,一个类应该仅有一个引起它变化的原因。
单一职责的好处:

  1. 类的复杂性降低,实现什么职责都有清晰明确的定义;
  2. 可读性提高,复杂性降低,那当然可读性提高了;
  3. 可维护性提高,可读性提高,那当然更容易维护;
  4. 变更引起的风险降低,变更是必不可少的,但是接口的单一职责做的好,一个接口修改只对相应的实现类有影响。
public class SrpTest {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        userService.updateUserInfo(1, "userId", "userName", null);
        userService.updateUserInfo(2, "userId", null, "password");
    }
}

interface UserService{
    /**
     * @param optType 1修改用户名;2重置密码
     */
    void updateUserInfo(int optType, String userId, String userName, String password);
}

class UserServiceImpl implements UserService{
    @Override
    public void updateUserInfo(int optType, String userId, String userName, String password) {
        if(optType == 1){
            // 修改用户名
            System.out.println("修改用户名");
        }else if(optType == 2){
            // 重置密码
            System.out.println("重置密码");
        }
    }
}

其中updateUserInfo职责有修改用户名和重置密码,如果我们需要修改重置密码逻辑,就会对updateUserInfo影响,违背单一职责原则。我们可以做如下修改:

public class SrpTest {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        userService.updateUserName("userId", "userName");
        userService.updatePassword("userId", "password");
    }
}

interface UserService{
    void updateUserName(String userId, String userName);
    void updatePassword(String userId, String password);
}

class UserServiceImpl implements UserService{
    @Override
    public void updateUserName(String userId, String userName) {
        // 修改用户名
        System.out.println("修改用户名");
    }
    @Override
    public void updatePassword(String userId, String password) {
        // 修改用户名
        System.out.println("重置密码");
    }
}
2、开发-关闭原则OCP(Open-Closed Principle)

所谓开放-关闭原则,指的是,一个类应该对扩展开放,对修改关闭。也叫开闭原则。

3、里氏替换原则LSP(Liskov Substitution Principle)

所谓里氏替换原则,指的是,子类型必须能够替换掉它们的父类型。
子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法。

public class LspTest {
    public static void main(String[] args) {
        ClassFather classFather = new ClassFather();
        System.out.println(classFather.method("hello", "world"));
        ClassSon classSon = new ClassSon();
        System.out.println(classSon.method("hello", "world"));
    }
}

class ClassFather{
    public String method(String a, String b){
        return a + "+" + b;
    }
}
class ClassSon extends ClassFather{
    @Override
    public String method(String a, String b) {
        return a + "-" + b;
    }
}

运行结果:

hello+world
hello-world

子类中可以增加自己特有的方法。

public class LspTest {
    public static void main(String[] args) {
        ClassFather classFather = new ClassFather();
        System.out.println(classFather.method("hello", "world"));
        ClassSon classSon = new ClassSon();
        System.out.println(classSon.method("hello", "world"));
        System.out.println("newMethod:"+classSon.newMethod("hello", "world"));
    }
}

class ClassFather{
    public String method(String a, String b){
        return a + "+" + b;
    }
}
class ClassSon extends ClassFather{
    public String newMethod(String a, String b) {
        return a + "-" + b;
    }
}

运行结果:

hello+world
hello+world
newMethod:hello-world

当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。

public class LspTest {
    public static void main(String[] args) {
        HashMap<String, Object> map = new HashMap<>();
        ClassFather classFather = new ClassFather();
        System.out.println(classFather.method(map));
        ClassSon classSon = new ClassSon();
        System.out.println(classSon.method(map));
    }
}

class ClassFather{
    public String method(HashMap<String, Object> map){
        return "this is father's method";
    }
}
class ClassSon extends ClassFather{
    public String method(Map<String, Object> map) {
        return "this is son's method";
    }
}

运行结果:

this is father's method
this is father's method

当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

public class LspTest {
    public static void main(String[] args) {
        ClassFather classSon = new ClassSon();
        classSon.method();
    }
}

abstract class ClassFather{
    abstract Map<String, Object> method();
}
class ClassSon extends ClassFather{
    @Override
    HashMap<String, Object> method() {
        System.out.println("this is son's method");
        return null;
    }
}

运行结果:

this is son's method
4、依赖倒置原则DIP(Dependence Inversion Principle)

所谓依赖倒置原则,指的是,要依赖于抽象,不要依赖于具体类。
面向接口编程。抽象指的是接口或抽象类,细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。

5、接口隔离原则ISP(Interface Segregation Principle)

所谓接口隔离原则,指的是,不应该强迫客户依赖于它们不用的方法。
怎么理解呢?通俗一点就是说接口尽量细分,把不需要的方法尽量写在2个不同的接口上。

6、最少知识原则LKP(Least KnowLedge Principle)

所谓最少知识原则,指的是,只和你的朋友谈话。最少知识原则要求我们的方法调用必须保持在一定的界限范围之内,尽量减少对象的依赖关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值