当前位置: 首页 > news >正文

岳阳网站推广国内专业seo公司

岳阳网站推广,国内专业seo公司,合肥注册公司流程和费用,米兰网的网络营销是什么文章目录 前言一、聚合组合继承依赖1.1、继承1.2、组合1.3、聚合1.4、依赖 二、单一职责原则2.1、单一职责原则反面案例2.2、单一职责原则反面案例的改进 三、接口隔离原则3.1、接口隔离原则反面案例3.2、接口隔离原则反面案例的改进 四、依赖倒转原则4.1、依赖… 文章目录 前言一、聚合组合继承依赖1.1、继承1.2、组合1.3、聚合1.4、依赖 二、单一职责原则2.1、单一职责原则反面案例2.2、单一职责原则反面案例的改进 三、接口隔离原则3.1、接口隔离原则反面案例3.2、接口隔离原则反面案例的改进 四、依赖倒转原则4.1、依赖倒转原则反面案例4.1、依赖倒转原则反面案例的改进 五、里氏替换原则5.1、里氏替换原则反面案例5.2、里氏替换原则反面案例的改进 六、开闭原则6.1、开闭原则反面案例6.2、开闭原则反面案例的改进 七、迪米特原则7.1、迪米特原则反面案例7.2、迪米特原则反面案例的改进 八、合成复用原则8.1、合成复用原则反面案例8.2、合成复用原则反面案例的改进 前言 本篇是设计模式专题笔记的前置理论篇介绍软件设计的七大原则单一职责原则、接口隔离原则、依赖倒转原则、里氏替换原则、开闭原则、迪米特法则、合成复用原则。上述七大原则既是软件设计的原则也是总结出23种设计模式的核心思想。不仅是学习设计模式的前置理论更是对Java面向对象三大特征的延伸扩展。 一、聚合组合继承依赖 在介绍七大原则之前首先需要明白什么是聚合、组合、依赖、继承。 1.1、继承 继承是面向对象的三大特征之一。A类继承了B类就拥有了B类的一切特征。如果A类重写了B类的某个方法该方法在A中会以重写的生效。很多中间件、框架的自定义配置即是用自定义类继承框架中原有的父类重写其中的方法。   但是使用继承很大程度上也会破坏七大原则应该慎用继承。个人理解何时使用继承最简单的就是学生类可以继承人类猫不能继承人类。即没有共性的类之间不要使用继承如果两者之间只是代码相似可以用组合代替继承。 1.2、组合 组合是一种强“拥有”关系表示一个类完全负责另一个类的生命周期包含的对象依附于整体对象存在。这种关系通常用来描述“整体-部分”关系且部分对象不可分离。整体销毁时部分对象也随之销毁因为部分对象是在整体对象中创建的。 class Engine {public void start() {System.out.println(Engine starts.);} }class Car {private Engine engine;public Car() { // 组合关系Car 自己创建 Enginethis.engine new Engine();}public void start() {engine.start();System.out.println(Car starts.);} }public class CompositionExample {public static void main(String[] args) {Car car new Car(); // Car 创建并拥有 Enginecar.start();} } 1.3、聚合 聚合是一种弱“拥有”关系表示一个类包含另一个类的对象作为其属性但被包含对象可以独立存在。整体并不控制部分的生命周期。 class Engine {public void start() {System.out.println(Engine starts.);} }class Car {private Engine engine;public Car(Engine engine) { // 通过构造方法传递 Enginethis.engine engine;}public void start() {engine.start();System.out.println(Car starts.);} }public class AggregationExample {public static void main(String[] args) {Engine engine new Engine(); // Engine 可以独立存在Car car new Car(engine); // Car 聚合了 Enginecar.start();} } 1.4、依赖 依赖是一种非常松散的关系表示一个类使用另一个类的功能但它们的生命周期彼此独立。 class Printer {public void printDocument(String document) {System.out.println(Printing: document);} }class User {public void usePrinter(Printer printer, String document) {printer.printDocument(document);} }public class DependencyExample {public static void main(String[] args) {Printer printer new Printer(); // 创建 Printer 对象User user new User(); // 创建 User 对象user.usePrinter(printer, My Document); // User 依赖于 Printer 的功能} } 二、单一职责原则 单一职责原则的核心思想在于一个类或下推到一个方法只去做一件事或者一类逻辑相同的事情。注意此一件事并不代表一个类中只能存在一个方法。例如我们有一个OrderService顾名思义应该在该类中做和订单相关的操作比如下单修改订单状态撤单等。而不是再混入一些用户相关操作。 2.1、单一职责原则反面案例 /*** 单一职责原则案例1*/ public class Demo1 {public static void main(String[] args) {Vehicle vehicle new Vehicle();vehicle.run(汽车);vehicle.run(船);vehicle.run(飞机);} }/*** 违反单一职责原则不同类的交通工具都打出了在公路上行驶* 实际上各自的行驶方式是不一样的* 这种写法把所有的情况都笼统地放在了一个方法中*/ class Vehicle{public void run(String vehicle){System.out.println(vehicle 在公路上行驶);} }2.2、单一职责原则反面案例的改进 /*** 单一职责原则案例2* 这种方式是在类的层面上进行了拆分* 将不同的交通工具的行驶方式拆分到了不同的类中* 在结构简单每个类中代码量少的时候没必要*/ public class Demo2 {public static void main(String[] args) {RoadVehicle roadVehicle new RoadVehicle();roadVehicle.run(汽车);AirVehicle airVehicle new AirVehicle();airVehicle.run(飞机);WaterVehicle waterVehicle new WaterVehicle();waterVehicle.run(船);} }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 在水上航行);} } /*** 单一职责原则案例3**/ public class Demo3 {public static void main(String[] args) {Vehicle2 vehicle2 new Vehicle2();vehicle2.airRun(飞机);vehicle2.roadRun(汽车);vehicle2.waterRun(船);} }/*** 这种方式是在方法层面进行了拆分每个方法只做一件事*/ class Vehicle2{public void roadRun(String vehicle){System.out.println(vehicle 在公路上行驶);}public void airRun(String vehicle){System.out.println(vehicle 在天空中飞行);}public void waterRun(String vehicle){System.out.println(vehicle 在水上航行);} }三、接口隔离原则 接口隔离原则的核心思想在于客户端不应该依赖于它不需要的接口。简单来说接口隔离原则建议将大的、庞杂的接口拆分成多个小的、专注的接口以减少类或模块对不必要方法的依赖。   当一个接口包含了多个方法时可能会导致一些实现该接口的类不得不实现它们不需要的方法。这会增加代码的复杂性造成不必要的耦合从而降低系统的灵活性和可维护性。 3.1、接口隔离原则反面案例 /*** 接口隔离原则* 现在有i1一个接口。它有B,C两个实现类* B和D实现了接口的所有方法* A通过接口使用B 但是A只会用到接口中的123方法* C通过接口使用D 但是C只会用到接口的145方法* 虽然AC只会用到接口中的部分方法但是B和D因为implement关键字的特性必须被迫实现接口的所有方法*/ public class Demo1 {public static void main(String[] args) {A a new A();a.depend1(new B());a.depend2(new B());a.depend3(new B());} }interface I1{void method1();void method2();void method3();void method4();void method5(); }class B implements I1{Overridepublic void method1() {System.out.println(B实现了I1的method1);}Overridepublic void method2() {System.out.println(B实现了I1的method2);}Overridepublic void method3() {System.out.println(B实现了I1的method3);}Overridepublic void method4() {System.out.println(B实现了I1的method4);}Overridepublic void method5() {System.out.println(B实现了I1的method5);} }class D implements I1{Overridepublic void method1() {System.out.println(D实现了I1的method1);}Overridepublic void method2() {System.out.println(D实现了I1的method2);}Overridepublic void method3() {System.out.println(D实现了I1的method3);}Overridepublic void method4() {System.out.println(D实现了I1的method4);}Overridepublic void method5() {System.out.println(D实现了I1的method5);} }class A{public void depend1(I1 i1){i1.method1();}public void depend2(I1 i1){i1.method2();}public void depend3(I1 i1){i1.method3();} }class C{public void depend1(I1 i1){i1.method1();}public void depend4(I1 i1){i1.method4();}public void depend5(I1 i1){i1.method5();} }3.2、接口隔离原则反面案例的改进 /***A通过接口使用B 但是A只会用到接口中的123方法 * C通过接口使用D 但是C只会用到接口的145方法* 就拆出三个接口接口一只有1方法让B,D实现接口二有2,3方法让B实现接口三有4,5方法让D实现。* 即B和D无需实现多余的方法 **/ public class Demo2 {public static void main(String[] args) {A1 a1 new A1();a1.depend1(new B1()); // a1.depend1(new D1());a1.depend3(new B1());a1.depend2(new B1());C1 c1 new C1();c1.depend1(new D1());c1.depend4(new D1());c1.depend4(new D1());} }interface Inter1{void method1(); }interface Inter2{void method2();void method3(); }interface Inter3{void method4();void method5(); }class B1 implements Inter1,Inter2{Overridepublic void method1() {System.out.println(B实现了Inter1的method1);}Overridepublic void method2() {System.out.println(B实现了Inter2的method2);}Overridepublic void method3() {System.out.println(B实现了Inter2的method3);} }class D1 implements Inter1,Inter3{Overridepublic void method1() {System.out.println(D实现了Inter1的method1);}Overridepublic void method4() {System.out.println(D实现了Inter3的method4);}Overridepublic void method5() {System.out.println(D实现了Inter3的method5);} }class A1{public void depend1(Inter1 inter1){inter1.method1();}public void depend2(Inter2 inter2){inter2.method2();}public void depend3(Inter2 inter2){inter2.method3();} }class C1{public void depend1(Inter1 inter1){inter1.method1();}public void depend4(Inter3 inter3){inter3.method4();}public void depend5(Inter3 inter3){inter3.method5();}}四、依赖倒转原则 依赖倒转原则的核心思想在于面向接口编程即高层模块不应该依赖低层模块。两者都应该依赖抽象。 抽象不应该依赖于细节。细节应该依赖于抽象。即高层模块和低层模块之间的依赖关系应该通过抽象接口或抽象类来连接。   这里不得不提到抽象类或接口的作用简单地说两者皆是一种规范作为模版屏蔽了实现的细节。具体的实现都是交给子类去完成。 4.1、依赖倒转原则反面案例 在下面的案例中发送邮件是一个具体的实现用户在接受时也是接受了一个具体的实现。那么如果我现在不是发送邮件而是需要发送短信或者微信呢   那么就需要改动接收方的代码将传入的Email改成Message或者WeChat等。 public class Demo1 {public static void main(String[] args) {new Person().receive(new Email());} }class Email{public String sendEmail(){return 发送邮件;} }class Person{public void receive(Email email){System.out.println(email.sendEmail());} }4.1、依赖倒转原则反面案例的改进 在改进的代码中选择将发送微信短信或者邮件的动作抽象成一个Message接口在接受方法中只需要传入Message接口调用接受方法时传入该接口对应的实现即可也是面向对象多态特性的体现 /*** 依赖倒转原则案例* 面向接口编程 只需要传递对应的实现类即可*/ public class Demo2 {public static void main(String[] args) {new Person().receive(new Email());new Person().receive(new Wechat());} }interface Message{String sendMessage(); }class Email implements Message{Overridepublic String sendMessage() {return 发送邮件;} }class Wechat implements Message{Overridepublic String sendMessage() {return 发送微信;} }class Person{public void receive(Message message){System.out.println(message.sendMessage());} }五、里氏替换原则 里氏替换原则的核心思想在于要求子类能够完全替代父类使用且不改变原有程序的正确性和行为。这意味着子类必须遵循父类定义的契约确保在继承层次结构中任何父类对象可以被子类对象所替换并且不会引发错误或改变系统行为。并且子类应该在不破坏父类已有行为的基础上提供更多的功能而不是改变父类的功能。   如果要满足该原则就需要尽量不重写父类中的方法。从某种程度来说是否失去了继承的意义其实不然里氏替换原则只是告诉我们不能滥用继承。里氏替换原则的核心目的是避免“强加不合理的行为”。即当你设计类层次结构时应该确保父类的行为和子类的行为在语义上是一致的。就如最开始的案例一样人可以继承人类去吃米饭而猫不能继承人类去吃米饭而应该吃猫粮。 5.1、里氏替换原则反面案例 /*** 里氏替换原则案例*/ public class Demo1 {public static void main(String[] args) {} }class A{public int func1(int num1,int num2){return num1 - num2;} }/*** B继承了A。无意中重写了func1方法导致达不到预期的效果*/ class B extends A{Overridepublic int func1(int num1, int num2) {return num1 num2;}public int func2(int num1,int num2){return func1(num1,num2)9;} }5.2、里氏替换原则反面案例的改进 /*** 里氏替换原则案例*/ public class Demo2 {public static void main(String[] args) {} }/*** 将func1抽取到一个公共的接口中哪个类需要用到func1就自己实现接口去写自己的逻辑*/ interface Base{int func1(int num1,int num2); }class A implements Base{Overridepublic int func1(int num1,int num2){return num1 - num2;} }/*** 如果B一定要用到A中的func1的逻辑就使用组合的方式*/ class B implements Base{private A a new A();Overridepublic int func1(int num1, int num2) {return num1 num2;}public int func2(int num1,int num2){return a.func1(num1,num2)9;} }六、开闭原则 开闭原则的核心思想在于面对使用方的修改关闭面对提供方的扩展开放即需求变化或新需求出现时我们应该能够通过增加新的代码如新的类或方法来扩展系统的功能。现有的代码不应被修改特别是已经经过测试并投入使用的部分。通过扩展而不是修改避免破坏现有的功能以及增加回归测试的成本。   这一点在实际工作中深有体会如果因为修改而破坏了原有的功能以及修改一处导致其他位置出现问题牵一发而动全身只能是说明最初的设计存在问题没有考虑完全。 6.1、开闭原则反面案例 /*** 测试开闭原则*/ public class Demo1 {public static void main(String[] args) {} }/*** 如果这个时候又要加一个画其他图形的需求呢* 那么需要改动if条件判断还要加一个新方法*/ class GraphicEditor{public void drawShape(Shape s){if (s.type 1){this.drawRectangle();}else if (s.type 2){this.drawCircle();}}public void drawRectangle(){System.out.println(画矩形);}public void drawCircle(){System.out.println(画圆);}}class Shape{int type; }class Rectangle extends Shape{public Rectangle(){super.type 1;} }class Circle extends Shape{public Circle(){super.type 2;} } 6.2、开闭原则反面案例的改进 实际上也是依赖倒转原则的体现利用接口或者抽象类作为中间层解耦。 /*** 测试开闭原则* 改进*/ public class Demo2 {public static void main(String[] args) {new Rectangle().draw();} }/*** 将画图改造成抽象类要画什么图形就自己继承抽象类加上自己的逻辑即可*/ abstract class GraphicEditor{void draw(){} }class Rectangle extends GraphicEditor{Overridevoid draw() {System.out.println(画矩形);} }class Circle extends GraphicEditor{Overridevoid draw() {System.out.println(画圆形);} }class Triangle extends GraphicEditor{Overridevoid draw() {System.out.println(画三角形);} }七、迪米特原则 迪米特原则的核心思想在于和本类功能相关的代码就应该尽量放在本类的相关方法中而不是放在方法的调用方。即调用方不需要关心被调用方法的具体实现这也是面向对象和面向过程的区别。即对象应该尽可能地少知道其他对象的内部实现或细节。   并且对象之间的交互应该尽量局限在直接的合作伙伴即直接的成员变量、方法参数或者构造函数注入的对象之间而避免调用链过长的对象。 7.1、迪米特原则反面案例 /*** 演示迪米特法则*/ public class Demo1 {public static void main(String[] args) {SchoolManager schoolManager new SchoolManager();schoolManager.printAll(new CollageManager());} }class Employee{private String id;/*** 获取* return id*/public String getId() {return id;}/*** 设置* param id*/public void setId(String id) {this.id id;}}class CollageEmployee{private String id;/*** 获取* return id*/public String getId() {return id;}/*** 设置* param id*/public void setId(String id) {this.id id;} }class CollageManager{public ListCollageEmployee getAllCollageEmployee(){ArrayListCollageEmployee employeeEmployees new ArrayList();for (int i 0; i 10; i) {CollageEmployee employeeEmployee new CollageEmployee();employeeEmployee.setId(学院员工id i);employeeEmployees.add(employeeEmployee);}return employeeEmployees;} }class SchoolManager{//CollageEmployee违反了迪米特原则在printAll中不关心CollageManager 是怎么把自己员工的信息打印出来的//应该把打印分公司员工的 信息 放到CollageManager类中public ListEmployee getAllEmployee(){ArrayListEmployee employeeEmployees new ArrayList();for (int i 0; i 5 ; i) {Employee employeeEmployee new Employee();employeeEmployee.setId(学校总部员工 i);employeeEmployees.add(employeeEmployee);}return employeeEmployees;}public void printAll(CollageManager collageManager){ListCollageEmployee allCollageEmployee collageManager.getAllCollageEmployee();System.out.println(分公司员工-------------);for (CollageEmployee c : allCollageEmployee) {System.out.println(c.getId());}ListEmployee allEmployee this.getAllEmployee();System.out.println(总公司员工-------------);for (Employee employee : allEmployee) {System.out.println(employee.getId());}} }7.2、迪米特原则反面案例的改进 package com.light.principle.demeter.demo2;import java.util.ArrayList; import java.util.List;/*** 演示迪米特法则*/ public class Demo2 {public static void main(String[] args) {SchoolManager schoolManager new SchoolManager();schoolManager.printAll(new CollageManager());} }class Employee{private String id;/*** 获取* return id*/public String getId() {return id;}/*** 设置* param id*/public void setId(String id) {this.id id;}}class CollageEmployee{private String id;/*** 获取* return id*/public String getId() {return id;}/*** 设置* param id*/public void setId(String id) {this.id id;} }class CollageManager{public ListCollageEmployee getAllCollageEmployee(){ArrayListCollageEmployee employeeEmployees new ArrayList();for (int i 0; i 10; i) {CollageEmployee employeeEmployee new CollageEmployee();employeeEmployee.setId(学院员工id i);employeeEmployees.add(employeeEmployee);}return employeeEmployees;}//把打印员工信息放回到CollageManager类中public void printCollageEmployee(){ListCollageEmployee allCollageEmployee this.getAllCollageEmployee();System.out.println(分公司员工-------------);for (CollageEmployee c : allCollageEmployee) {System.out.println(c.getId());}} }class SchoolManager{public ListEmployee getAllEmployee(){ArrayListEmployee employeeEmployees new ArrayList();for (int i 0; i 5 ; i) {Employee employeeEmployee new Employee();employeeEmployee.setId(学校总部员工 i);employeeEmployees.add(employeeEmployee);}return employeeEmployees;}public void printAll(CollageManager collageManager){collageManager.printCollageEmployee();ListEmployee allEmployee this.getAllEmployee();System.out.println(总公司员工-------------);for (Employee employee : allEmployee) {System.out.println(employee.getId());}} }八、合成复用原则 合成复用原则实际上是对里氏替换原则的一个总结它的核心思想是通过对象组合Composition而不是继承Inheritance来实现复用。在设计系统时我们应该优先考虑将不同的功能或者行为封装成独立的对象然后通过组合这些对象来实现所需的功能而不是通过继承关系来复用代码。 8.1、合成复用原则反面案例 class Bird {public void fly() {System.out.println(Flying);}public void eat() {System.out.println(Eating);} }class Sparrow extends Bird {public void chirp() {System.out.println(Chirping);} }class Penguin extends Bird {public void swim() {System.out.println(Swimming);}// 企鹅不应该飞行但继承了 Bird可能会误用 fly()Overridepublic void fly() {throw new UnsupportedOperationException(Penguins cant fly);} } 8.2、合成复用原则反面案例的改进 在改进案例中将飞行和游泳拆分为了两个独立的接口细化了各自的功能实现类可以按需选择。 // 定义飞行行为接口 interface Flyable {void fly(); }// 定义游泳行为接口 interface Swimmable {void swim(); }// Bird 类只负责鸟类的通用行为 class Bird {public void eat() {System.out.println(Eating);} }// 麻雀类通过实现 Flyable 实现飞行 class Sparrow extends Bird implements Flyable {public void fly() {System.out.println(Sparrow flying);}public void chirp() {System.out.println(Chirping);} }// 企鹅类通过实现 Swimmable 实现游泳 class Penguin extends Bird implements Swimmable {public void swim() {System.out.println(Penguin swimming);} } 从下一篇开始对23种设计模式进行逐条解析。
http://www.hkea.cn/news/14436307/

相关文章:

  • 做行程好的网站wordpress子主题插件
  • 莱西市城乡建设局网站招标网站哪个比较好
  • git做网站根目录票务网站开发端口
  • 行业网站建设网站快照优化公司
  • 高端网站建设与发展wordpress本地网站上传
  • 网站建设一般要多钱品牌推广图片
  • 长治市建设厅官方网站制作免费网站的平台
  • ps软件下载官方网站长春做网站选长春万网
  • 建站前期准备新乡市建设路小学网站
  • 珠海低价网站建设做网站要多少钱
  • 巴彦淖尔市网站制作wordpress 开发框架
  • 修改散文网站华商网
  • 网站首页设计过程济宁网站开发
  • 网站代码模板编写网络营销师官网
  • 农村电商网站建设分类网络营销的基础与前提是什么理论
  • 网站建设续费是什么费用wordpress怎么写html
  • 如何理解电子商务网站建设与管理公司网站建设制作难么
  • 做电影网站有风险吗企业网站用什么域名
  • 网站基本建设是什么吉林中岩峰建设有限公司网站
  • h5网站开发是什么意思wordpress 域名更换
  • 杭州商城网站建设python对接wordpress
  • 黄石网站开发WordPress怎么新建导航菜单
  • 1号店网站模板下载职业生涯规划大赛官网报名
  • 网站建设多少钱个人做网站需要规划好什么
  • 星级酒店网站建设公司宿州网站建设费用
  • 手机网站域名和pc域名的区别wordpress 自动博客
  • 网站推广策划案新手学计算机编程入门
  • 网站建设平台汉龙编程培训机构哪里好
  • 怎么做房产网站游戏外包公司要不要去
  • 东方资产营销网站wordpress评价