主页 > IT业界  > 

一、《重学设计模式》-设计模式简介

一、《重学设计模式》-设计模式简介
1. 设计模式分类 序号模式&描述包括1创建型模式1.工厂 2.抽象工厂 3.建造者 4.原型 5.单例2结构型模式1.适配器 2.桥接 3.过滤器 4.组合 5.装饰器 6.外观 7.享元 8.代理3行为模式1.责任链 2.命令 3.解释器 4.迭代器 5.中介者 6.备忘录 7.观察者 8.状态 9.空对象 10.策略 11.模板 12.访问者 2. 设计模式关系图

3. 设计模式的七大原则 单一职责( 一个类和方法只做一件事 )里⽒替换( 多态,子类可扩展父类 )依赖倒置( 细节依赖抽象,下层依赖上层 )接口隔离( 建⽴单一接口 )迪米特原则( 最少知道,降低耦合 )开闭原则( 抽象架构,扩展实现 )合成复用原则 1. 单一职责

方案一

public class Demo1 { public static void main(String[] args) { SingleResponsibility singleResponsibility = new SingleResponsibility(); singleResponsibility.run("小鸡"); singleResponsibility.run("小鱼"); singleResponsibility.run("小鸟"); } static class SingleResponsibility { public void run(String name) { System.out.println(name + " 在跑"); } } } ========================= 小鸡 在跑 小鱼 在跑 小鸟 在跑

以上代码run方法违反了单一职责原则,解决方案也很简单,将SingleResponsibility 分成三个,陆地、天空、水中

方案二

public class Demo2 { public static void main(String[] args) { SingleResponsibilityLand singleResponsibility1 = new SingleResponsibilityLand(); SingleResponsibilitySky singleResponsibility2 = new SingleResponsibilitySky(); SingleResponsibilityWater singleResponsibility3 = new SingleResponsibilityWater(); singleResponsibility1.run("小鸡"); singleResponsibility3.run("小鱼"); singleResponsibility2.run("小鸟"); } static class SingleResponsibilityLand { public void run(String name) { System.out.println(name + " 在跑"); } } static class SingleResponsibilitySky { public void run(String name) { System.out.println(name + " 在飞"); } } static class SingleResponsibilityWater { public void run(String name) { System.out.println(name + " 在游"); } } } =================== 小鸡 在跑 小鱼 在游 小鸟 在飞

成功解决了方案一的缺陷,遵守了单一职责,但是这样做改动很大,分解了多个类,修改了main方法

方案三

public static void main(String[] args) { SingleResponsibility singleResponsibility = new SingleResponsibility(); singleResponsibility.runLand("小鸡"); singleResponsibility.runWater("小鱼"); singleResponsibility.runSky("小鸟"); } static class SingleResponsibility { public void runLand(String name) { System.out.println(name + " 在跑"); } public void runWater(String name) { System.out.println(name + " 在游"); } public void runSky(String name) { System.out.println(name + " 在飞"); } }

这种方法没有对最初的类进行大的修改,只是增加了方法,虽然没有在类级别遵守单一职责,但是在方法上面满足了单一职责

注意事项

降低类的复杂度,一个类只负责一项职责提高类的可读性,可维护性降低变更引起的风险通常情况下,应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单一职责原则;只有类中方法数量足够少,可以在方法级别保持单一职责原则 2. 接口隔离原则

方案一

public class Demo2_1 { public static void main(String[] args) { A a = new A(); a.opration1(new C()); a.opration2(new C()); a.opration5(new C()); B b = new B(); b.opration1(new D()); b.opration3(new D()); b.opration4(new D()); } } interface Interface1{ void opration1(); void opration2(); void opration3(); void opration4(); void opration5(); } class A { public void opration1(Interface1 interface1) { interface1.opration1(); } public void opration2(Interface1 interface1) { interface1.opration2(); } public void opration5(Interface1 interface1) { interface1.opration5(); } } class B { public void opration1(Interface1 interface1) { interface1.opration1(); } public void opration3(Interface1 interface1) { interface1.opration3(); } public void opration4(Interface1 interface1) { interface1.opration4(); } } class C implements Interface1{ @Override public void opration1() { System.out.println("C opration1"); } @Override public void opration2() { System.out.println("C opration2"); } @Override public void opration3() { System.out.println("C opration3"); } @Override public void opration4() { System.out.println("C opration4"); } @Override public void opration5() { System.out.println("C opration5"); } } class D implements Interface1{ @Override public void opration1() { System.out.println("D opration1"); } @Override public void opration2() { System.out.println("D opration2"); } @Override public void opration3() { System.out.println("D opration3"); } @Override public void opration4() { System.out.println("D opration4"); } @Override public void opration5() { System.out.println("D opration5"); } }

类A通过接口 Interface1 依赖类C,类B通过接口 Interface1 依赖类D,如果接口 Interface1对于类C和类D来说不是最小接口,那么类C和类D必须去实现他们不需要的方法, 改进办法,将interface1拆分成三个接口,让他们分别实现不同的接口

方案二

public class Demo2_2 { public static void main(String[] args) { A1 a = new A1(); a.opration1(new C1()); a.opration2(new C1()); a.opration5(new C1()); B1 b = new B1(); b.opration1(new D1()); b.opration3(new D1()); b.opration4(new D1()); } } interface Interface21{ void opration1(); } interface Interface22{ void opration2(); void opration5(); } interface Interface23{ void opration3(); void opration4(); } class A1 { public void opration1(C1 interface1) { interface1.opration1(); } public void opration2(C1 interface1) { interface1.opration2(); } public void opration5(C1 interface1) { interface1.opration5(); } } class B1 { public void opration1(D1 interface1) { interface1.opration1(); } public void opration3(D1 interface1) { interface1.opration3(); } public void opration4(D1 interface1) { interface1.opration4(); } } class C1 implements Interface21, Interface22{ @Override public void opration1() { System.out.println("C opration1"); } @Override public void opration2() { System.out.println("C opration2"); } @Override public void opration5() { System.out.println("C opration5"); } } class D1 implements Interface21, Interface23{ @Override public void opration1() { System.out.println("D opration1"); } @Override public void opration3() { System.out.println("D opration3"); } @Override public void opration4() { System.out.println("D opration4"); } }

方案二将接口全部拆分,依赖类只需要实现自己需要的接口

3. 依赖倒转(接口或抽象类)

方案一

public class Demo3_1 { public static void main(String[] args) { Somebody somebody = new Somebody(); somebody.receive(new Email()); } } class Email{ public void say(){ System.out.println("邮件"); } } class Somebody{ // 传参固定,扩展其他内容有困难 public void receive(Email email){ email.say(); } }

Somebody如果要实现接收微信,短信消息扩展困难

方案二

public class Demo3_2 { public static void main(String[] args) { XiaoQiang xiaoQiang = new XiaoQiang(); xiaoQiang.receive(new Wechat()); xiaoQiang.receive(new SMS()); } } interface Message{ void say(); } class Wechat implements Message{ public void say(){ System.out.println("微信"); } } class SMS implements Message{ public void say(){ System.out.println("短信"); } } class XiaoQiang{ public void receive(Message message){ message.say(); } }

方案二提供公共接口,参数用接口形式传递,可以接收不同类型的消息,同时好扩展

依赖关系传递

接口传递构造器传递setter方法传递 4. 里氏替换原则(继承)

子类尽量不要重写父类的方法,继承实际上是让两个类的耦合性增强,适当的使用聚合、组合、依赖来解决问题

方案一

public class Demo4_1 { public static void main(String[] args) { A4 a = new A4(); System.out.println("1+1="+a.fun1(1,1)); System.out.println("1+3="+a.fun1(1,3)); B4 b = new B4(); System.out.println("1+1="+b.fun1(1,1)); System.out.println("1+1+9="+b.fun2(1,1)); } } class A4 { public int fun1(int a , int b ){ return a+b; } } class B4 extends A4{ //重写父类方法 public int fun1(int a , int b ){ return a-b; } public int fun2(int a , int b ){ return fun1(a,b) + 9; } }

方案一存在问题,B继承A 但是修改了A方法的逻辑,导致后面使用相同方法但是意义不一样,和预想结果发生偏差

方案二

public class Demo4_2 { public static void main(String[] args) { A42 a = new A42(); System.out.println("1+1=" + a.fun1(1, 1)); System.out.println("1+3=" + a.fun1(1, 3)); B42 b = new B42(); System.out.println("1+1=" + b.fun1(1, 1)); System.out.println("1+1+9=" + b.fun2(1, 1)); } } class Base4 { } class A42 extends Base4 { public int fun1(int a, int b) { return a + b; } } class B42 extends Base4 { //通过组合方式解决方法名称相同,内容不同 A42 a42 = new A42(); //重写父类方法 public int fun1(int a, int b) { return a - b; } public int fun2(int a, int b) { return fun1(a, b) + 9; } public int fun3(int a, int b) { return a42.fun1(a, b); } }

提取公共类,实现各自继承,解决单一继承修改方法导致方法意义变更的问题,如果B想使用A,使用组合方式实现

5. 开闭原则

扩展开放(提供方),修改关闭(使用方),抽象构建框架,实现扩展细节

软件变化尽量通过扩展,而不是通过修改

方案一

public class Demo5_1 { public static void main(String[] args) { Bank bank = new Bank(); bank.pay(new JDPay()); bank.pay(new WechatPay()); bank.pay(new AliPay()); } } class Bank { // 使用方 public void pay(Pay pay) { if (pay.type == 1) { System.out.println("京东支付"); } else if (pay.type == 2) { System.out.println("微信支付"); } else if (pay.type == 3) { System.out.println("支付宝支付"); } } } class Pay { int type; } class JDPay extends Pay { public JDPay() { super.type = 1; } } class WechatPay extends Pay { public WechatPay() { super.type = 2; } } class AliPay extends Pay { public AliPay() { super.type = 3; } }

方案一,当我们想要使用银联支付的时候,需要添加银联支付的类,需要修改实用类,都要修改,不符合开闭原则

方案二

public class Demo5_2 { public static void main(String[] args) { Bank bank = new Bank(); bank.pay(new JDPay()); bank.pay(new WechatPay()); bank.pay(new AliPay()); } } class Bank { // 使用方 public void pay(Pay pay) { pay.pay(); } } abstract class Pay { int type; abstract void pay(); } class JDPay extends Pay { public JDPay() { super.type = 1; } @Override void pay() { System.out.println("京东支付"); } } class WechatPay extends Pay { public WechatPay() { super.type = 2; } @Override void pay() { System.out.println("微信支付"); } } class AliPay extends Pay { public AliPay() { super.type = 3; } @Override void pay() { System.out.println("支付宝支付"); } }

使用方法二,使用类,无需改动,以后扩展其他支付,只需要增加对应的支付类

6. 迪米特法则

只与直接朋友通信,

直接朋友的定义,成员变量、方法参数,方法返回值,局部变量不是直接朋友

不是直接朋友的类,是陌生的类

判断思路

在类里面找非直接朋友,如果找到,就将非直接朋友迁移到其他类中

7. 合成复用原则

尽量使用聚合/合成方式,而不是使用集成

简单讲类A 有方法f1,类B想使用f1,简单的办法,B继承A,但是继承就提高了AB之间的耦合,A可以作为参数传递给B使用A方法的方法,A也可以作为B的成员变量通过set方法传递过去,也可以直接在B中通过new来进行组合

8.设计模式的核心思想

把需要变化的独立出来,不要和那些不需要变化的代码混合起来

针对接口编程而不是针对实现编程

为了交互对象之间松耦合设计而努力

标签:

一、《重学设计模式》-设计模式简介由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“一、《重学设计模式》-设计模式简介