七大原则:
单一职责原则(SRP)
开放-封闭原则(OCP)——面向对象设计的终极目标
里氏代换原则(LSP)
依赖倒转原则(DIP)
合成/聚合复用原则(CARP)
接口隔离原则(ISP)
迪米特法则(LoD)
一,单一职责原则:
原:
class Vehicle{
public void run(String vehicle)
{ System.out. println(vehicle + " 在公路上跑 ");}
}
public class Java1 { public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.run("摩托车");
vehicle.run("汽车");
vehicle.run("飞机");}
}
改进1:
class RoadVehicle{
public void run(String vehicle) {
System.out.println(vehicle+"在公路上跑"); }
}
class AirVehicle {
public void run(String vehicle)
{ System.out. println(vehicle + " 在天空中飞 "); }
}
class WaterVehicle {
public void run(String vehicle)
{ System.out. println(vehicle + " 在水里游 "); }
}
public class Java1 {
public static void main(String[] args) {
RoadVehicle roadVehicle = new RoadVehicle();
roadVehicle.run("摩托车");
roadVehicle.run("汽车");
AirVehicle airVehicle = new AirVehicle();
airVehicle.run("飞机");
WaterVehicle waterVehicle = new WaterVehicle();
waterVehicle.run("轮船"); }
}
改进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 Java1 {
public static void main(String[] args) {
Vehicle2 Vehicle = new Vehicle2();
Vehicle.run("摩托车");
Vehicle.run("汽车");
Vehicle.runAir("飞机");
Vehicle.runWater("轮船"); }
}
二,开放封闭原则:
原:
class Rectangle{
void draw(){
System.out.println("矩形"); }
}
class Circle {
void draw(){ System.out.println("圆形"); }
}
class Triangle { //新增三角形
void draw(){ System.out.println("三角形"); }
}
class GraphicDraw {
void drawgraph(int type){
if(type==1){ Rectangle rec=new Rectangle(); rec.draw();}
else if(type==2){ Circle c=new Circle(); c.draw();}
else if(type==3){ //新增绘制三角形
Triangle t=new Triangle(); t.draw();}
}
}
public class Java1 {
public static void main(String[] args) {
GraphicDraw graphicdraw=new GraphicDraw();
graphicdraw.drawgraph(2); //客户端肯定要改
}
}
改进:
abstract class Shape {
public abstract void draw(); //抽象方法
}
class GraphicDraw { //新增绘制图形不需修改此类
void drawgraph(Shape s){ s.draw(); }
}
class Rectangle extends Shape {
public void draw(){System.out.println("矩形"); }
}
class Circle extends Shape {
public void draw(){ System.out.println("圆形"); }
}
class Triangle extends Shape { //新增三角形
public void draw(){ System.out.println("三角形"); }
}
public class Java1 {
public static void main(String[] args) {
GraphicDraw graphicdraw=new GraphicDraw();
graphicdraw.drawgraph(new Circle());
graphicdraw.drawgraph(new Rectangle());
graphicdraw.drawgraph(new Triangle());
}
}
三,里氏替换原则:
原:
class A{
public int func1(int num1, int num2){
return num1-num2; }
}
class B extends A{
public int func1(int a,int b){
return a+b;}
public int func2(int a, int b){
return func1(a,b)+9;}
}
public class Liskov {
public static void main(String[] args) {
A a = new A();
System.out.println("11-3=" +a.func1(11,3));
System.out.println("1-8="+a.func1(1,8));
System.out.println ("-------");
B b = new B();
System.out.println("11-3=" + b.func1(11,3));
//这里本意是求出11-3
System.out.println("1-8="+ b.func1(1,8));
System.out.println("11+3+9="+b.func2(11,3));
}
}
改进:
package java1;
class Base {
//把更加基础的方法和成员写到Base类
}
// A类
class A extends Base {
//返回两个数的差
public int func1(int num1, int num2) {
return num1 - num2; }
}
class B extends Base{
A a=new A();//组合
//A a; public setA(A a){ this.a=a;} 这就是聚合
//如果a在func3的参数表里new出来则就是依赖
public int func1(int a,int b){
return a+b; }
public int func2(int a, int b){
return func1(a,b)+9; }
public int func3(int a, int b){
return this.a.func1(a,b); }
}
public class Java1 {
public static void main(String[] args) {
A a = new A();
System.out.println("11-3=" +a.func1(11,3));
System.out.println("1-8="+a.func1(1,8));
System.out.println ("-------");
B b= new B();
//因为B类不再继承A类,因此调用者,不会再func1是求减法
//调用完成的功能就会很明确
System. out.println("11+3=" + b. func1(11, 3));//这里本意是求出11+3
System. out.println("1+8=" + b.func1(1, 8));// 1+8
System. out.println("11+3+9=" + b.func2(11, 3));
//使用组合仍然可以使用到A类相关方法
System. out.println("11-3=" + b.func3(11, 3));// 这里本意是求出11-3
}
}
四,依赖倒转原则:
原:
class Email{
public String getInfo() {
return "电子邮件信息: hello world ";
}
}
/* Person 类 接受消息,将Email类 作为参数 产生了依赖
如果 参数发生变化,即接受的是微信 或短信 整个方法需要改动 */
class Person{ public void receive(Email email) {
System.out.println(email.getInfo());
}
}
public class Java1 {
public static void main(String[] args) {
Person person = new Person();
person.receive(new Email());
}
}
改进:
interface IReciver{ public String getInfo(); }
class Email implements IReciver{
public String getInfo() {
return "电子邮件信息: hello world ";
}
}
class WenXin implements IReciver{
public String getInfo() { return "微信信息: hello WenXin "; }
}
/* Person 类 接受消息 将IReciver 接口 作为参数 产生了依赖 */
class Person{
public void receive(IReciver reciver) {
System.out.println(reciver.getInfo());
}
}
public class Java1 {
public static void main(String[] args) {
Person person = new Person();
person.receive(new Email());
//传入不同实现类 实现不同的接受
person.receive(new WenXin());
}
}
五:合成/聚合复用原则:
原:
class B extend A{
this.opertion2() ; //但是一三方法都用不到但也都继承过来了
}
改:
class B{
opertion (A a) {
a. opertion2() ;
}
}
或
class B{
A a;
void setA(A a){
a. opertion2();
}
}
或
class B{
A a=new A( );
a. opertion2();
}
六,接口隔离原则:
不应该依赖不需要的接口,即一个类对另一个类的依赖应该 建立在最小的接口上
原:
//接口
interface Interface1 {
void operation1();
void operation2();
void operation3();
void operation4();
void operation5();
}
//类B实现接口Interface1
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");
}
}
//类D实现接口Interface1
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");
}
}
//类A通过接口Interface1依赖(使用) 类B,但是只会用到1,2,3方法
class A{
public void depend1(Interface1 i) {
i.operation1();
}
public void depend2(Interface1 i) {
i.operation2();
}
public void depend3(Interface1 i) {
i.operation3();
}
}
//类C通过接口Interface1依赖(使用) 类D,但是只会用到1,4,5方法
class C{
public void depend1(Interface1 i) {
i.operation1();
}
public void depend4(Interface1 i) {
i.operation4();
}
public void depend5(Interface1 i) {
i.operation5();
}
}
public class segregation {
public static void main(String[] args) {
A a=new A();
C c=new C();
//类A 通过接口 依赖类B
a.depend1(new B());
a.depend2(new B());
a.depend3(new B());
//类C 通过接口 依赖类D
c.depend1(new D());
c.depend4(new D());
c.depend5(new D());
}
}
}
}
改:
interface Interface1 {
void operation1();
}
interface Interface2 {
void operation2();
void operation3();
}
interface Interface3 {
void operation4();
void operation5();
}
//类B 实现接口Interface1 ,Interface2的所有方法
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");
}
}
//类A 通过接口 Interface1,Interface2 依赖 (使用)类B 只会 用到方法1,2,3
class A {
public void depend1(Interface1 i) {
i.operation1();
}
public void depend2(Interface2 i) {
i.operation2();
}
public void depend3(Interface2 i) {
i.operation3();
}
}
//类D实现接口Interface1,Interface3 的所有方法
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");
}
}
//类C 通过接口 Interface1,Interface3 依赖 (使用)类D 只会 用到方法1,4,5
class C {
public void depend1(Interface1 i) {
i.operation1();
}
public void depend4(Interface3 i) {
i.operation4();
}
public void depend5(Interface3 i) {
i.operation5();
}
}
public class segregation {
public static void main(String[] args) {
A a=new A();
C c=new C();
//类A 通过接口 依赖类B
a.depend1(new B());
a.depend2(new B());
a.depend3(new B());
//类C 通过接口 依赖类D
c.depend1(new D());
c.depend4(new D());
c.depend5(new D());
}
}
}
}
七,迪米特法则:
迪米特法则还有个更简单的定义:只与直接的朋友通信
直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之 间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很 多,依赖,关联,组合,聚合等其中称出现成员变量方法参数,方法返回值中的类为直接的朋友。
而出现在局部变量中的类不是直接 的朋友。
也就是说,陌生的类最好不要以局部变量的形式出现在类的内部。
原:
import java.util.ArrayList;
import java.util.List;
//学校总部员工类
class Employee {
private String id;
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
//学院的员工类
class CollegeEmployee{
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
//管理学院员工的管理类
class CollegeManager{
public List<CollegeEmployee> getAllEmployee(){
List<CollegeEmployee> list = new ArrayList();
for(int i = 0; i < 10; i++) {
CollegeEmployee emp = new CollegeEmployee();
emp.setId("学院员工 id = " + i);
list.add(emp);
}
return list;
}
}
//学校管理类
//分析SchoolMangager 类的直接朋友有哪些Employee,CollegeManager
//CollegeEmployee 不是直接朋友而是一个陌生类,这样违背了迪米特法则
class SchoolManager{
public List<Employee> getAllEmployee(){
List<Employee> list = new ArrayList();
for(int i = 0; i < 5; i++) {
Employee emp = new Employee();
emp.setId("学校总部的员工id = " + i);
list.add(emp);
}
return list;
}
//该方法完成输出学校总部和学院员工信息(id)
void printAllEmployee(CollegeManager sub){
//分析问题
//1. 这里的CollegeEmployee不是 SchoolManager的直接朋友
//2. CollegeEmployee 是以局部变量方式出现在SchoolManager
//3. 违反了迪米特法则
//获取到学院员工
List<CollegeEmployee> list1 = sub.getAllEmployee();
System.out.println("-------学院员工---------");
for (CollegeEmployee employee : list1) {
System.out.println(employee.getId());
}
//获取到学校总部的员工
List<Employee> list2 = this.getAllEmployee();
System.out.println("-------学校总部员工---------");
for (Employee employee : list2) {
System.out.println(employee.getId());
}
}
}
public class Demeter {
public static void main(String[] args) {
//创建了一个SchoolManager对象
SchoolManager schoolManager = new SchoolManager();
//输出学院的员工id 和 学校总部的员工信息
schoolManager.printAllEmployee(new CollegeManager());
}
}
改:
import java.util.ArrayList;
import java.util.List;
//学校总部员工类
class Employee {
private String id;
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
//学院的员工类
class CollegeEmployee{
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
//管理学院员工的管理类
class CollegeManager{
public List<CollegeEmployee> getAllEmployee(){
List<CollegeEmployee> list = new ArrayList();
for(int i = 0; i < 10; i++) {
CollegeEmployee emp = new CollegeEmployee();
emp.setId("学院员工 id = " + i);
list.add(emp);
}
return list;
}
void printEmployee(){
List<CollegeEmployee> list1 = getAllEmployee();
System.out.println("-------学院员工---------");
for (CollegeEmployee employee : list1) {
System.out.println(employee.getId());
}
}
}
//学校管理类
//分析SchoolMangager 类的直接朋友有哪些Employee,CollegeManager
//CollegeEmployee 不是直接朋友而是一个陌生类,这样违背了迪米特法则
class SchoolManager{
public List<Employee> getAllEmployee(){
List<Employee> list = new ArrayList();
for(int i = 0; i < 5; i++) {
Employee emp = new Employee();
emp.setId("学校总部的员工id = " + i);
list.add(emp);
}
return list;
}
//该方法完成输出学校总部和学院员工信息(id)
void printAllEmployee(CollegeManager sub){
//分析问题
//1. 将输出学院的员工方法,封装到CollegeManager
sub.printEmployee();
//获取到学校总部的员工
List<Employee> list2 = this.getAllEmployee();
System.out.println("-------学校总部员工---------");
for (Employee employee : list2) {
System.out.println(employee.getId());
}
}
}
public class Demeter {
public static void main(String[] args) {
//创建了一个SchoolManager对象
SchoolManager schoolManager = new SchoolManager();
//输出学院的员工id 和 学校总部的员工信息
schoolManager.printAllEmployee(new CollegeManager());
}
}