设计模式-设计原则
设计原则
1.依赖倒置
高层不应该依赖低层,两者应该都依赖于抽象
抽象不应该依赖具体实现,具体应该依赖于抽象
自动驾驶系统公司是高层,汽车生产商是底层,自动驾驶系统不应该依赖于各种车型系统底层进行实现,因为这是耦合度高,车型多样。而应该依赖于抽象的自动驾驶行业标准,汽车厂商也应该依赖于自动驾驶标准,可以配置各种自动驾驶系统
2.开放封闭
一个类对扩展,也就是组合和继承开放,对修改关闭
3.面向接口
客户程序面对一个未知的系统,不应该知道里面的数据流动,而应该面向该系统的接口即可
从而减少系统各部分依赖关系
4. 单一职责
一个方法尽可能只做一件事,一个类应该仅有一个引起它变化的原因
不遵循单一原则
package com.study.singleResponsibilty;
public class SingleResponsibility1 {
public static void main(String[] args) {
// 类实例化
Vehicle v1 = new Vehicle("汽车");
Vehicle v2 = new Vehicle("飞机");
Vehicle v3 = new Vehicle("轮船");
// 调用行驶方法
v1.mov();
v2.mov();
v3.mov();
}
}
// 交通工具类
class Vehicle{
private final String vehicleType ;
// 构造方法
public Vehicle(String vehicleType) {
this.vehicleType = vehicleType;
}
//方法: 行驶
public void mov(){
System.out.println(this.vehicleType + "在马路上行驶");
}
}
严格遵循单一原则
package com.study.singleResponsibilty;
public class SingleResponsibility3 {
public static void main(String[] args) {
// 类实例化
RoadVehicle rv = new RoadVehicle("汽车");
AirVehicle av = new AirVehicle("飞机");
SeaVehicle sv = new SeaVehicle("轮船");
// 调用方法
rv.mov();
av.mov();
sv.mov();
}
}
// 陆地交通工具类
class RoadVehicle {
private final String vehicleType;
// 构造方法
public RoadVehicle(String vehicleType) {
this.vehicleType = vehicleType;
}
// 方法: 行驶
public void mov(){
System.out.println(this.vehicleType + "在公路行驶");
}
}
// 空中交通工具类
class AirVehicle {
private final String vehicleType;
// 构造方法
public AirVehicle(String vehicleType) {
this.vehicleType = vehicleType;
}
// 方法: 行驶
public void mov(){
System.out.println(this.vehicleType + "在空中行驶");
}
}
// 海上交通工具类
class SeaVehicle {
private final String vehicleType;
// 构造方法
public SeaVehicle(String vehicleType) {
this.vehicleType = vehicleType;
}
// 方法: 行驶
public void mov(){
System.out.println(this.vehicleType + "在海上行驶");
}
}
5. 里式替换
子类型必须能够替换掉它的父类型;主要出现在子类覆盖父类实现,原来使用父类型的程序可能出 现错误;覆盖了父类方法却没有实现父类方法的职责;
- 子类必须完全实现父类的抽象方法,且不可重写父类非抽象方法
- 子类可以实现特有方法
- 子类可透明访问父类的所有方法
不遵循里氏原则
package com.study.liskov;
public class Liskov1 {
public static void main(String[] args) {
A a = new A();
ExtendA ea = new ExtendA();
System.out.print("输入A: ");
a.info();
System.out.print("再输出A: ");
ea.info();
}
}
class A{
public void info() {
System.out.println("我是A");
}
public void baseMethod1(){
System.out.println("基础方法1");
}
public void baseMethod2() {
System.out.println("基础方法2");
}
}
class ExtendA extends A{
public void info() {
System.out.println("我是extendA");
}
}
父类的info被破坏
遵循里氏原则
package com.study.liskov;
public class Liskov2 {
public static void main(String[] args) {
A1 a = new A1();
ExtendA1 ea = new ExtendA1();
System.out.print("输出A: ");
a.info();
System.out.print("再输出A: ");
ea.info();
System.out.print("ExtendA 中使用 A: ");
ea.UseA(a);
System.out.print("参数为BaseA, 传入A: ");
ea.UseBaseA(a);
}
}
abstract class BaseA {
// A类 的基础方法
public void info() {
System.out.println("我是A");
}
public void baseMethod1() {
System.out.println("基础方法1");
}
public void baseMethod2() {
System.out.println("基础方法2");
}
abstract public void run();
}
class A1 extends BaseA {
public void uniqueA() {
System.out.println("A 特有方法");
}
@Override
public void run() {
System.out.println("A -> running......");
}
}
class ExtendA1 extends BaseA {
A1 a = new A1();
@Override
public void run() {
System.out.println("ExtendA -> running......");
}
public void UseA(A1 a){
a.uniqueA();
}
public void UseBaseA(BaseA ba) {
ba.baseMethod1();
}
}
- 将所有基础方法写入BaseA中,在写A和ExtendA时放置了子类重写父类的问题
- 在ExtendA 中使用A, 使用组合的方式
- 由于子类能够透明的完全访问父类, 当需要一个BaseA参数时,可以传入一个A
6.接口隔离
不应该强迫客户依赖于它们不用的方法,比如一个类需要实现A B方法,这时候继承一个接口里面有ABC方法,就不满足接口隔离原则
不遵守接口隔离原则的代码
// IHouseWork 做饭、扫地、洗衣服
// CleanHouseWork : 扫地、洗衣服
// OtherHouseWork : 做饭
// Nanny : 扫地、洗衣服
// Chef : 做饭
package com.study.interfaceIsolation;
public class interfaceIsolation1 {
public static void main(String[] args) {
}
}
interface IHouseWork{
void cooking();
void sweepFloor();
void wishClothes();
}
class CleanHouseWork implements IHouseWork{
@Override
public void cooking() {
System.out.println("CleanHouseWork 实现了 IHouseWork.cooking");
}
@Override
public void sweepFloor() {
System.out.println("CleanHouseWork 实现了 IHouseWork.sweepFloor");
}
@Override
public void wishClothes() {
System.out.println("CleanHouseWork 实现了 IHouseWork.wishClothes");
}
}
class OtherHouseWork implements IHouseWork{
@Override
public void cooking() {
System.out.println("OtherHouseWork 实现了 IHouseWork.cooking");
}
@Override
public void sweepFloor() {
System.out.println("OtherHouseWork 实现了 IHouseWork.sweepFloor");
}
@Override
public void wishClothes() {
System.out.println("OtherHouseWork 实现了 IHouseWork.wishClothes");
}
}
// Nanny类, 通过IHouseWork接口依赖CleanHouseWork类
class Nanny{
public void dependSweepFloor(IHouseWork i){
i.sweepFloor();
}
public void dependWishClothes(IHouseWork i){
i.wishClothes();
}
}
// Chef类, 通过IHouseWork接口依赖OthterHouseWork类
class Chef{
public void dependCooking(IHouseWork i){
i.cooking();
}
}
遵守接口隔离的代码
// ICleanHouseWork 扫地、洗衣服
// IOtherHouseWork 做饭
// CleanHouseWork : 扫地、洗衣服
// OtherHouseWork : 做饭
// Nanny : 扫地、洗衣服
// Chef : 做饭
package com.study.interfaceIsolation;
public class InterfaceIsolation2 {
public static void main(String[] args) {
Nanny1 n = new Nanny1();
Chef1 c = new Chef1();
n.dependSweepFloor(new CleanHouseWork1());
n.dependWishClothes(new CleanHouseWork1());
c.dependCooking(new OtherHouseWork1());
}
}
interface ICleanHouseWork {
void sweepFloor();
void wishClothes();
}
interface IOtherHouseWork {
void cooking();
}
class CleanHouseWork1 implements ICleanHouseWork{
@Override
public void sweepFloor() {
System.out.println("CleanHouseWork1 实现了 sweepFloor方法");
}
@Override
public void wishClothes() {
System.out.println("CleanHouseWork1 实现了 wishClothes方法");
}
}
class OtherHouseWork1 implements IOtherHouseWork{
@Override
public void cooking() {
System.out.println("OtherHouseWork1 实现了 cooking方法");
}
}
class Nanny1{
public void dependSweepFloor(ICleanHouseWork i){
i.sweepFloor();
}
public void dependWishClothes(ICleanHouseWork i){
i.wishClothes();
}
}
class Chef1{
public void dependCooking(IOtherHouseWork i){
i.cooking();
}
}
组合优于继承
组合耦合度低,继承耦合度高