1.开放封闭原则
开放封闭原则(Open-Closed Principle):一个软件实体应当对扩展开放,则修改关闭。在设计一个模块时,应当使得这个模块可以在不被修改的前提下被扩展。也就是说,应当可以在不必修改源代码的情况下修改这个模块的行为。设计的目的便在于面对需求的改变而保持系统的相对稳定,从而使得系统可以很容易的从一个版本升级到另一个版本。
怎样做到开放封闭原则:
实际上,绝对封闭的系统是不存在的。无论模块是怎么封闭,到最后,总还是有一些无法封闭的变化。而我们的思路就是:既然不能做到完全封闭,那我们就应该对那些变化封闭,那些变化隔离做出选择。我们做出选择,然后将那些无法封闭的变化抽象出来,进行隔离,允许扩展,尽可能的减少系统的开发。当系统变化来临时,我们要及时的做出反应。
我们并不害怕改变的到来。当变化到来时,我们首先需要做的不是修改代码,而是尽可能的将变化抽象出来进行隔离,然后进行扩展。面对需求的变化,对程序的修改应该是尽可能通过添加代码来实现,而不是通过修改代码来实现。
实际上,变化或者可能的变化来的越早,抽象就越容易,相对的,代码的维护也就越容易;而当项目接近于完成而来的需求变化,则会使抽象变得很困难——这个困难,并不是抽象本身的困难,抽象本身并没有困难,困难在于系统的架构已经完成修改牵扯的方面太多而使得抽象工作变得很困难。
package com.ibeifeng.ex2;
/*
* 银行业务员接口,是所有银行业务员的抽象父类。
*/
public interface BankWorker {
public void operation();
}
package com.ibeifeng.ex2;
/*
* 负责取款业务的业务员
*/
public class DrawingBankWorker implements BankWorker{
public void operation() {
System.out.println("进行取款操作");
}
}
package com.ibeifeng.ex2;
public class JiJinBankWorker implements BankWorker {
public void operation() {
System.out.println("进行基金申购操作");
}
}
package com.ibeifeng.ex2;
/*
* 负责存款业务的业务员
*/
public class SavingBankWorker implements BankWorker {
public void operation() {
System.out.println("进行存款操作");
}
}
package com.ibeifeng.ex2;
/*
* 负责转账业务的业务员
*/
public class ZhuanZhangBankWorker implements BankWorker {
public void operation() {
System.out.println("进行转账操作");
}
}
package com.ibeifeng.ex2;
public class MainClass {
public static void main(String[] args) {
BankWorker bankWorker = new SavingBankWorker();
bankWorker.operation();
BankWorker bankWorker2 = new DrawingBankWorker();
bankWorker2.operation();
BankWorker bankWorker3 = new ZhuanZhangBankWorker();
bankWorker3.operation();
BankWorker bankWorker4 = new JiJinBankWorker();
bankWorker4.operation();
}
}
开放封闭原则的优越性:
1.通过扩展已有的软件系统,可以提供新的行为,以满足对软件的新需求,是变化中的软件有一定的适应性和灵活性。
2.已有的软件模块,特别是最重要的抽象模块不能再修改,这就使变化中的软件系统有一定的稳定性和延续性。
2.单一职责原则
单一职责原则(Single Responsibility Principle ):就一个类而言,应该仅有一个引起它变化的原因。
单一职责原则示例:
接受客户端输入并提交到数据库。
原有设计: 一个类负责接受客户端输入,对客户端输入进行校验,连接数据库,并提交数据到数据库。
现有设计:一个功能也就是一个职责由一个类来负责.
package com.ibeifeng.ex2;
import java.util.Scanner;
public class Input {
private String username;
private String upassword;
//获得客户端输入
public void shuru() {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名");
username = scanner.nextLine();
System.out.println("请输入密码");
upassword = scanner.nextLine();
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUpassword() {
return upassword;
}
public void setUpassword(String upassword) {
this.upassword = upassword;
}
}
package com.ibeifeng.ex2;
public class DBManager {
//连接数据库
public static void getConnection() {
System.out.println("获得数据库连接");
}
}
package com.ibeifeng.ex2;
public class DAOImp {
//进行数据操作
public void save(String username,String upassword) {
System.out.println("将" + username + "保存到了数据库");
System.out.println("将" + upassword + "保存到了数据库");
}
}
package com.ibeifeng.ex2;
public class Validator {
//进行数据校验
public boolean validate(String username, String upassword) {
if(username == null || "".equals(username.trim())) {
System.out.println("用户名不能为空");
return false;
}
if(upassword == null || "".equals(upassword.trim())) {
System.out.println("密码不能为空");
return false;
}
return true;
}
}
package com.ibeifeng.ex2;
public class MainClass {
public static void main(String[] args) {
Input input = new Input();
input.shuru();
Validator validator = new Validator();
if(validator.validate(input.getUsername(), input.getUpassword())){
DBManager.getConnection();
DAOImp dao = new DAOImp();
dao.save(input.getUsername(), input.getUpassword());
}
}
}
3.里氏代换原则
里氏代换原则(Liskov Substitution Principle):一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类和子类对象的区别。也就是说,在软件里面,把父类替换成它的子类,程序的行为没有变化。
一个软件实体如果使用的是一个子类的话,那么它不能适用于其父类。
package com.ibeifeng.ex3;
public interface Sibianxing {
public long getWidth();
public long getHeight();
}
package com.ibeifeng.ex3;
public class ZhengFX implements Sibianxing{
private long side;
public long getHeight() {
return this.getSide();
}
public long getWidth() {
return this.getSide();
}
public void setHeight(long height) {
this.setSide(height);
}
public void setWidth(long width) {
this.setSide(width);
}
public long getSide() {
return side;
}
public void setSide(long side) {
this.side = side;
}
}
package com.ibeifeng.ex3;
public class ChangFX implements Sibianxing{
private long width;
private long height;
public long getWidth() {
return width;
}
public void setWidth(long width) {
this.width = width;
}
public long getHeight() {
return height;
}
public void setHeight(long height) {
this.height = height;
}
}
package com.ibeifeng.ex3;
public class MainClass {
public static void main(String[] args) {
ChangFX changfx = new ChangFX();
changfx.setHeight(10);
changfx.setWidth(20);
test(changfx);
ZhengFX zhengfx = new ZhengFX();
zhengfx.setHeight(10);
test(zhengfx);
}
public static void test(Sibianxing sibianxing) {
System.out.println(sibianxing.getHeight());
System.out.println(sibianxing.getWidth());
}
// public static void resize(Sibianxing sibianxing) {
// while(sibianxing.getHeight() <= sibianxing.getWidth()) {
// sibianxing.setHeight(sibianxing.getHeight() + 1);
// test(sibianxing);
// }
// }
}
4.依赖倒转原则
传统的过程式设计倾向于使高层次的模块依赖于低层次的模块,抽象层依赖于具体的层次。
依赖倒转(Dependence Inversion Principle ):
1.抽象不应该依赖于细节,细节应该依赖于抽象。
2.高层模块不依赖底层模块,两者都依赖抽象。
怎样做到依赖倒转:
1.工厂方法模式
2.模板方法模式
3.迭代子模式
/*
* 硬盘的抽象类
*/
public abstract class HardDisk {
public abstract void doSomething();
}
public class XiJieHardDisk extends HardDisk {
public void doSomething() {
System.out.println("this is xijieHardDisk");
}
}
public class XiShuHardDisk extends HardDisk {
public void doSomething() {
System.out.println("this is xishuHardDisk");
}
}
/*
* 主板抽象类
*/
public abstract class MainBoard {
public abstract void doSomething();
}
public class WeiXingMainBoard extends MainBoard {
public void doSomething() {
System.out.println("this is weixingMainBoard");
}
}
/*
* 华硕主板
*/
public class HuaSuoMainBoard extends MainBoard{
public void doSomething() {
System.out.println("this is huasuoMainBoard");
}
}
/*
* 内存的抽象类
*/
public abstract class Memory {
public abstract void doSomething();
}
public class JinBangMemory extends Memory {
public void doSomething() {
System.out.println("this is jinbangMemory");
}
}
public class JinShiDunMemory extends Memory {
public void doSomething() {
System.out.println("this is jinshidunMemory");
}
}
/*
* 电脑
*/
public class Computer {
private MainBoard mainBoard;
private Memory memory;
private HardDisk harddisk;
public MainBoard getMainBoard() {
return mainBoard;
}
public void setMainBoard(MainBoard mainBoard) {
this.mainBoard = mainBoard;
}
public Memory getMemory() {
return memory;
}
public void setMemory(Memory memory) {
this.memory = memory;
}
public HardDisk getHarddisk() {
return harddisk;
}
public void setHarddisk(HardDisk harddisk) {
this.harddisk = harddisk;
}
public void display() {
mainBoard.doSomething();
memory.doSomething();
harddisk.doSomething();
}
}
public class MainClass {
public static void main(String[] args) {
Computer computer = new Computer();
computer.setMainBoard(new HuaSuoMainBoard());
computer.setMemory(new JinShiDunMemory());
computer.setHarddisk(new XiJieHardDisk());
computer.display();
System.out.println("-------------");
computer.setMainBoard(new WeiXingMainBoard());
computer.display();
}
}
5.迪米特法则
迪米特法则(Law of Demeter )又叫做最少知识原则,也就是说,一个对象应当对其他对象尽可能少的了解。迪米特法则最初是用来作为面向对象的系统设计风格的一种法则,于1987年秋天由lan holland在美国东北大学为一个叫做迪米特的项目设计提出的。
狭义的迪米特法则:
如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一类的某一个方法的话,可以通过第三者转发这个调用。
迪米特法则和设计模式:
1.外观模式
2.中介者模式
package com.ibeifeng.ex4;
public class SomeOne {
private Friend friend;
private Stranger stranger;
public Stranger getStranger() {
return stranger;
}
public void setStranger(Stranger stranger) {
this.stranger = stranger;
}
public Friend getFriend() {
return friend;
}
public void setFriend(Friend friend) {
this.friend = friend;
}
public void play() {
System.out.println("someone play");
friend.play();
stranger.play();
}
}
package com.ibeifeng.ex4;
public abstract class Stranger {
public abstract void play();
}
package com.ibeifeng.ex4;
public class StrangerA extends Stranger {
public void play() {
System.out.println("strangerA play");
}
}
package com.ibeifeng.ex4;
public class Friend {
public void play(){
System.out.println("friends paly");
}
}
package com.ibeifeng.ex4;
public class MainClass {
public static void main(String[] args) {
SomeOne zhangsan = new SomeOne();
zhangsan.setFriend(new Friend());
zhangsan.setStranger(new StrangerA());
zhangsan.play();
}
}