简续
经过一周的学习对设计模式的基本原理有了一定的自我见解,我个人认为设计模式的七大原则有点像我们生活中对一个事物的评判,他往往无法做到面面俱到,无法满足全部的设计原则,实际开发中我们难免会面对业务的妥协,那么接下来我们就来看一下这七大原则我给起了一个外号叫做-江南七怪
江南七怪之开闭原则
首先我可以很明确的告诉大家一点就是-开闭原则是七大原则之首,可能这个概念比较抽象,简单来说就是我以后改代码的时候相对而言我只要改很少,很少的部分,那么兄弟,你可能无意间就莫名其妙的遵守了这个原则,那么开闭原则到底是个什么呢,比如我们有一个订单创建的manager,那么假如我这个manager最开始的时候只有创建天猫订单的方法代码应该是如下这样
package com.company;
public class opening {
public static void main(String[] args) {
createOrder createOrder = new createOrder();
createOrder.createOrders(new tmOrder());
}
}
class createOrder{
public void createOrders(order order){
if (order.type == 1){
createTm(order);
}
}
public void createTm(order tmOrder){
System.out.println("创建天猫订单");
}
}
class order{
int type;
}
class tmOrder extends order{
tmOrder(){
super.type=1;
}
}
这时候我们如果来了京东的单子我们就会改成这样
package com.company;
public class opening2 {
public static void main(String[] args) {
createOrder2 createOrder2 = new createOrder2();
createOrder2.createOrders(new tmOrder2());
// 加1
createOrder2.createOrders(new jdOrder2());
}
}
class createOrder2{
public void createOrders(order2 order){
if (order.type == 1){
createTm(order);
//加1
}else if (order.type == 2){
createJd(order);
}
}
public void createTm(order2 tmOrder){
System.out.println("创建天猫订单" + tmOrder.type);
}
// 加1
public void createJd(order2 jdOrder){
System.out.println("创建京东订单"+jdOrder.type);
}
}
class order2{
int type;
}
class tmOrder2 extends order2{
tmOrder2(){
super.type=1;
}
}
// 加1
class jdOrder2 extends order2{
jdOrder2(){
super.type=2;
}
}
我们的改动之处有五次,于是我们现在来遵守ocp原则改动一下
package com.company;
public class opening2 {
public static void main(String[] args) {
createOrder2 createOrder2 = new createOrder2();
createOrder2.createOrders(new tmOrder2());
createOrder2.createOrders(new jdOrder2());
createOrder2.createOrders(new dyOrder());
}
}
class createOrder2{
public void createOrders(order2 order){
order.orderCreate();
}
}
abstract class order2{
int type;
public abstract void orderCreate();
}
class tmOrder2 extends order2{
tmOrder2(){
super.type=1;
}
@Override
public void orderCreate() {
System.out.println("创建天猫订单" + type);
}
}
class jdOrder2 extends order2{
jdOrder2(){
super.type=2;
}
@Override
public void orderCreate() {
System.out.println("创建京东订单"+ type);
}
}
class dyOrder extends order2{
dyOrder(){
super.type=3;
}
@Override
public void orderCreate() {
System.out.println("创建抖音订单"+type);
}
}
我们只需要修改两次即可,是不是很快捷,方便,其实总结来说,开闭原则就是将修改经可能的留在提供方,使用方无需关注内部实现
江南七怪之单一职责原则
单一职责原则我觉得这是一个最好理解的,看名字就应该知道,其实就是一个类或者方法应该主要关注自己应该做的事情而不要过度的耦合,自己做自己的事情
package com.company;
public class single {
public static void main(String[] args) {
transportation transportation = new transportation();
transportation.run("汽车");
transportation.run("火车");
transportation.run("飞机");
transportation.run("轮船");
}
}
class transportation{
public void run(String var){
System.out.println(var + "在路上跑");
}
}
上述代码中我们可以看出,这个run()方法真的是啥都干啊,那这样不就违反我们的单一职责了,我们改造一下我们的代码
package com.company;
public class single2 {
public static void main(String[] args) {
transportationOnTheRoad transportationOnTheRoad = new transportationOnTheRoad();
transportationOnTheRoad.run("汽车");
transportationOnTheRoad.run("火车");
transportationSky transportationSky = new transportationSky();
transportationSky.run("飞机");
transportationonTheWater transportationonTheWater = new transportationonTheWater();
transportationonTheWater.run("轮船");
}
}
class transportationOnTheRoad{
public void run(String var){
System.out.println(var + "在路上跑");
}
}
class transportationSky{
public void run(String var){
System.out.println(var + "在天空跑");
}
}
class transportationonTheWater{
public void run(String var){
System.out.println(var + "在水上跑");
}
}
于是我们就变成各做各的,这也是我们常做的事情,你说我不单一,好,那我就新建一个类装这些事情,这样是不是就单一了,没错这样的确满足了单一,但是不觉得我们修改的量也太大了吧,不行不行,我们还要在改造一下
package com.company;
public class single3 {
public static void main(String[] args) {
transportation3 transportationOnTheRoad = new transportation3();
transportationOnTheRoad.runOnTheRoad("汽车");
transportationOnTheRoad.runOnTheRoad("火车");
transportationOnTheRoad.runtationSky("飞机");
transportationOnTheRoad.runTheWater("轮船");
}
}
class transportation3{
public void runOnTheRoad(String var){
System.out.println(var + "在路上跑");
}
public void runtationSky(String var){
System.out.println(var + "在天空跑");
}
public void runTheWater(String var){
System.out.println(var + "在水上跑");
}
}
这样是不是就改动小了很多,其实有时候我们需要自己去衡量是否应该将粒度下沉,从方法级别去做单一,也可以做类的单一
综上:在开发过程中依照面向对象的思想,对一些抽象的功能做类的单一,具体的实现可以做方法的单一
江南七怪之里氏代换原则
里氏替换原则其实一句话总结就是把具有相同行为的东西封装到更上一层的基类中,我们来看一段代码,大家可以复制出去看一下运行结果
package com.company;
public class RichterReplacement {
public static void main(String[] args) {
a a = new a();
System.out.println("6-5="+a.function1(6,5));
b b = new b();
System.out.println("6-5="+b.function1(6,5));
}
}
class a{
public int function1(int a, int b){
return a-b;
}
}
class b extends a{
@Override
public int function1(int a, int b){
return a+b;
}
public int function2(int c, int d){
return function1(c,d)+9;
}
}
聪明的你们肯定发现了,function1的方法已经被改变了原来的方法,这是后我们应该怎么办呢,我们既想要用这个方法又不想改变原来的方法这时候就是里氏替换中的说法,我们可以聚合,组合,依赖的方式进行操作,明确来说继承是属于一种耦合度很高的手段,接下来我们用里氏替换原则来实现一下
package com.company;
public class RichterReplacement2 {
public static void main(String[] args) {
a2 a2 = new a2();
System.out.println("6-5="+a2.function1(6,5));
b2 b = new b2();
System.out.println("6-5="+b.function1(6,5));
System.out.println("6-5="+b.function2(6,5));
System.out.println("6-5="+b.function3(6,5));
}
}
class base{
}
class a2 extends base{
public int function1(int a, int b){
return a-b;
}
}
class b2 extends base{
//这里用的就是组合的方式
private a a = new a();
public int function1(int a, int b){
return a+b;
}
public int function2(int c, int d){
return function1(c,d)+9;
}
public int function3(int c, int d){
return a.function1(c,d);
}
}
上面注释的地方就是组合的方式,后面会一一展示聚合,依赖的写法
江南七怪之依赖倒转原则
依赖倒转原则其实遵循三点:
1、底层接口都要有抽象类和接口
2、变量声明类型最好是抽象的接口,这样后面迭代起来方便扩展
3、最后就是要遵循里氏替换原则
废话不多说我们还是先来看反面代码
package com.company;
public class DependencyInversion {
public static void main(String[] args) {
Person person = new Person();
person.print(new qq());
}
}
class qq{
public String qqprint(){
return "QQ消息";
}
}
class Person{
public void print(qq qq){
System.out.println(qq.qqprint());
}
}
上面这段代码,可以看出这耦合度也太高了,环环相扣,肯定是不能让他们这样在一起,我们来改造一下
package com.company;
public class DependencyInversion2 {
public static void main(String[] args) {
person2 person = new person2();
person.print(new qq2());
person.print(new weixing());
}
}
interface IPerson{
public String newsPrint();
}
class qq2 implements IPerson {
@Override
public String newsPrint() {
return "qq";
}
}
class weixing implements IPerson{
@Override
public String newsPrint() {
return "weixin"; }
}
class person2{
public void print(IPerson iPerson){
System.out.println(iPerson.newsPrint());
}
}
于是我们的方法就被改造成这样了,综上就是依赖倒转原则
江南七怪之接口隔离原则
接口隔离原则相对与单一职责原则有一定的相似性,对于子类完全用不到的类单独抽离出一个新的接口,简单来说就是,用不到的我就不用去关心,老样子我们看一下反面例子
package com.company;
public class InterfaceIsolation {
}
interface classa{
public void fun1();
public void fun2();
public void fun3();
public void fun4();
public void fun5();
public void fun6();
}
class function1 implements classa{
@Override
public void fun1() {
}
@Override
public void fun2() {
}
@Override
public void fun3() {
}
@Override
public void fun4() {
}
@Override
public void fun5() {
}
@Override
public void fun6() {
}
}
上面这段代码其实我只想用1和2但是我却要全部实现,这样就造成的浪费,而接口隔离的原则就是让我们把不需要关心的类抽离出去。那么我们改造一下就是
package com.company;
public class InterfaceIsolation {
}
interface classa{
public void fun1();
public void fun2();
}
interface classb{
public void fun3();
public void fun4();
public void fun5();
public void fun6();
}
class function1 implements classa{
@Override
public void fun1() {
}
@Override
public void fun2() {
}
}
class function2 implements classb{
@Override
public void fun3() {
}
@Override
public void fun4() {
}
@Override
public void fun5() {
}
@Override
public void fun6() {
}
}
一眼就看出其实我们就是把接口功能独立出来,就可以了
江南七怪之合成复用原则
合成复用原则就记住一点能不用继承就别用继承
我们直接上代码
package com.company;
public class SyntheticTaking {
}
class function{
public void test01(){
System.out.println("001");
}
public void test02(){
System.out.println("001");
}
}
class function6 extends function{
}
class function7 extends function{
}
这时候我们6和7都继承了这个方法那么我们都拥有了改变这个类方法的权利,这时候我们对父类的把控就每月那么明确了,那么我们正确的写法应该是什么样呢?还是上代码
package com.company;
public class SyntheticTaking {
}
class function{
public void test01(){
System.out.println("001");
}
public void test02(){
System.out.println("001");
}
}
class function6 {
public void function7(function function){
function.test01();
}
}
我如果这样去改造一下是不是就可以避免,我用不到你也给我的烦心事
江南七怪之最少知道原则
最少知道简而言之就是,我使用方知道的越少越好,其实就是把我调用方的实现完全封闭起来只需要告诉我能得到什么就好了
总结
其实我们所有的法则都只有一个原则就是降低耦合度,对扩展开放对修改封闭,我们追求的永远只是降低耦合度而不是消灭耦合。