设计模式
设计模式的用处
设计模式七大原则
单一职责原则
-
基本介绍:一个类只应该负责一个职责 对类来说的,即一个类应该只负责一项职责。如类A负责两个不同职责:职责1,职责2。当职责1需求变更而改变A时,可能造成职责2执行错误,所以需要将类A的粒度分解为A1,A2
-
单一职责原则注意事项和细节
- 1)降低类的复杂度,一个类只负责一项职责。
- 2)提高类的可读性,可维护性
- 3)降低变更引起的风险
- 4)通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单一职
- 原则:只有类中方法数量足够少,可以在方法级别保持单一职责原则
package com.lmx.principle;
/**
* 单一职责原则
*/
public class Singleness {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
vehicle.run("汽车");
vehicle.runAir("飞机");
vehicle.runWarter("轮船");
}
}
/**
* 一般情况下一个类负责一件事
* 当类足够简单时,可在方法层面上进行划分
*/
class Vehicle {
public void run(String s) {
System.out.println(s + "在公路上跑");
}
public void runAir(String s) {
System.out.println(s + "在天空上飞");
}
public void runWarter(String s) {
System.out.println(s + "在水中行驶");
}
}
接口隔离原则
客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上
- 1)类A通过接口Interface1依赖类B,类C通过接口Interface1依赖类D,如果接口
Interface1对于类A和类c来说不是最小接口,那么类B和类D必须去实现他们不
需要的方法 - 2)将接口Interface1拆分为独立的几个接口,类A和类c分别与他们需要的接口建立
依赖关系。也就是采用接口隔离原则 - 3)接口Interface1中出现的方法,根据实际情况拆分为三个接口
- 4)代码实现
package com.lmx.principle.Interfaceisolation;
public class InterfaceIsolation {
public static void main(String[] args) {
}
}
interface interfance1 {
void operation1();
void operation2();
void operation3();
void operation4();
void operation5();
}
class B implements interfance1 {
@Override
public void operation1() {
System.out.println("B——operation1");
}
@Override
public void operation2() {
System.out.println("B——operation2");
}
@Override
public void operation3() {
System.out.println("B——operation3");
}
@Override
public void operation4() {
System.out.println("B——operation4");
}
@Override
public void operation5() {
System.out.println("B——operation5");
}
}
class D implements interfance1 {
@Override
public void operation1() {
System.out.println("D——operation1");
}
@Override
public void operation2() {
System.out.println("D——operation2");
}
@Override
public void operation3() {
System.out.println("D——operation3");
}
@Override
public void operation4() {
System.out.println("D——operation4");
}
@Override
public void operation5() {
System.out.println("D——operation5");
}
}
class A {
public void dependcy1(interfance1 interfance1) {
interfance1.operation1();
}
public void dependcy2(interfance1 interfance1) {
interfance1.operation2();
}
public void dependcy3(interfance1 interfance1) {
interfance1.operation3();
}
}
class C {
public void dependcy1(interfance1 interfance1) {
interfance1.operation1();
}
public void dependcy4(interfance1 interfance1) {
interfance1.operation4();
}
public void dependcy5(interfance1 interfance1) {
interfance1.operation5();
}
}
-
按照接口隔离之后的实现方法‘
package com.lmx.principle.Interfaceisolation; public class InterfaceIsolationnew { public static void main(String[] args) { A a = new A(); a.dependcy1(new B()); a.dependcy2(new B()); C c = new C(); c.dependcy1(new D()); } } interface interfance21 { void operation1(); } interface interfance22 { void operation2(); void operation3(); } interface interfance23 { void operation4(); void operation5(); } class B1 implements interfance21, interfance22 { @Override public void operation1() { System.out.println("B——operation1"); } @Override public void operation2() { System.out.println("B——operation2"); } @Override public void operation3() { System.out.println("B——operation3"); } } class D1 implements interfance21, interfance23 { @Override public void operation1() { System.out.println("D——operation1"); } @Override public void operation4() { System.out.println("D——operation4"); } @Override public void operation5() { System.out.println("D——operation5"); } } class A1 { public void dependcy1(interfance21 interfance1) { interfance1.operation1(); } public void dependcy2(interfance22 interfance1) { interfance1.operation2(); } public void dependcy3(interfance22 interfance1) { interfance1.operation3(); } } class C1 { public void dependcy1(interfance21 interfance1) { interfance1.operation1(); } public void dependcy4(interfance23 interfance1) { interfance1.operation4(); } public void dependcy5(interfance23 interfance1) { interfance1.operation5(); } }
- 按照接口隔离原则,将一个interfance拆分为3个接口,A、C实现对应的接口
依赖倒转原则
- 依赖倒转原则的注意事项和细节
- 1)低层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好」
- 2)变量的声明类型尽量是抽象类或接口,这样我们的变量引用和实际对象间,就存在
一个缓冲层,利于程序扩展和优化 - 3)继承时遵循里氏替换原则
public class DependencyInversion {
public static void main(String[] args) {
Email email = new Email();
Person person = new Person();
person.recieve(email);
}
}
class Email {
public String message() {
return "邮件消息";
}
}
class Person {
public void recieve(Email email) {
System.out.println(email.message());
}
}
- 存在问题:
- person对于Email的依赖过强,当preson后续需要接受微信消息、短信消息等时,需要重写recieve方法
package com.lmx.principle.dependencyInversion;
/**
* 依赖倒置原则的相关依赖
* 案例:preson接收消息的数据
*/
public class DependencyInversion {
public static void main(String[] args) {
Email email = new Email();
Person person = new Person();
person.recieve(email);
Wx wx = new Wx();
person.recieve(wx);
}
}
interface Message {
public String message();
}
class Email implements Message {
public String message() {
return "邮件消息";
}
}
class Wx implements Message {
public String message() {
return "微信消息";
}
}
class Person {
public void recieve(Message message) {
System.out.println(message.message());
}
}
- 未解决上述问题,将recieve的方法参数,修改为接口,不同的消息类型实现接口
依赖替换原则三种实现:
// 接口传递
//class Person {
//
// public void recieve(Message message) {
// System.out.println(message.message());
// }
//}
构造方法调用
//class Person {
//
// private Message message;
//
// public Person(Message message) {
// this.message = message;
// }
//
// public void recieve() {
// System.out.println(this.message.message());
//
// }
//}
// set方法调用
//class Person {
//
// private Message message;
//
// public void setMessage(Message message) {
// this.message = message;
// }
//
// public void recieve() {
// System.out.println(this.message.message());
//
// }
//}
里氏替换原则
- 在使用父类的地方,将父类换成子类,程序仍然运行无误
package com.lmx.principle.leeb;
/**
* 里氏替换原则
*/
public class Leeb {
public static void main(String[] args) {
A a = new A();
System.out.println("11-3" + a.func1(11, 3));
B b = new B();
System.out.println("11-3" + b.func1(11, 3));
System.out.println("11+3-9" + b.func2(11, 3, 9));
}
}
class A {
public Integer func1(int a, int b) {
return a - b;
}
}
class B extends A {
public Integer func1(int a, int b) {
return a + b;
}
public Integer func2(int a, int b, int c) {
return func1(a, b) - c;
}
}
- 问题:
- B类继承了A类,并且重写了A类的方法,造成了在调用B类方法时造成了错误
·
package com.lmx.principle.leeb;
/**
* 里氏替换原则
*/
public class Leeb {
public static void main(String[] args) {
A a = new A();
System.out.println("11-3" + a.func1(11, 3));
B b = new B();
System.out.println("11-3" + b.func3(11, 3));
System.out.println("11+3-9" + b.func2(11, 3, 9));
}
}
class Base {
}
class A extends Base {
public Integer func1(int a, int b) {
return a - b;
}
}
class B extends Base {
private A a = new A();
public Integer func1(int a, int b) {
return a + b;
}
public Integer func2(int a, int b, int c) {
return func1(a, b) - c;
}
public Integer func3(int c, int b) {
return a.func1(c, b);
}
}
开闭原则
package com.lmx.principle.openandclose;
/**
* 开闭原则
*/
public class OpenClose {
public static void main(String[] args) {
Cicle cicle = new Cicle();
Draw draw = new Draw();
draw.draw(cicle);
Sanjiao sanjiao = new Sanjiao();
draw.draw(sanjiao);
}
}
class Draw {
public void draw(Shape shape) {
shape.draw();
}
}
abstract class Shape {
private Integer type;
public Shape(Integer type) {
this.type = type;
}
abstract public void draw();
}
class Cicle extends Shape {
public Cicle() {
super(1);
}
@Override
public void draw() {
System.out.println("画圆");
}
}
class Sanjiao extends Shape {
public Sanjiao() {
super(2);
}
@Override
public void draw() {
System.out.println("画三角");
}
}