设计模式简介(一)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了设计模式简介(一),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含11013字,纯文字阅读大概需要16分钟。
内容图文
![设计模式简介(一)](/upload/InfoBanner/zyjiaocheng/998/3345cd6d095d4e85808d3131303050cb.jpg)
设计模式的定义
? 软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。
设计模式重要性
? 1、设计模式为程序提供可拓展性。
? 2、遵循设计模式可以为程序提供维修性,可读性,规范性。
? 3、 面试问题
? 4、设计模式无处不在
? 5、成为优秀程序员必备条件。
设计模式的目的
? 设计模式是为了让程序,具有更好的:代码复用性,可读性(规范性),可拓展性,可靠性,使程序呈现高内聚,低耦合的特性
设计模式七大原则
1、单一职责
定义
? 一个类应该只负责一项职责
注意事项和细节
? 1、降低类的复杂度,一个类只负责一项原则
? 2、提高类的可读性,可维护性。
? 3、降低变更引起的风险。
? 4、通常情况下,应当遵守单一职责原则。只有逻辑足够简单,才可以在代码级违反单一职责原则;只有类中方法数量足够少,可以在方法级别保持单一职责原则。
2、接口隔离
定义
? 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小接口上。
解释
? 1)类a通过接口 interface 1依赖b,类c通过接口 interface 1 依赖d,如果接口 interface 对于a 和c来说不是最小接口,那么类b和类d必须去实现他们不需要的方法。
? 2)将接口interface 1拆分为独立的几个接口,类a和类c分别为与他们需要的接口建立依赖关系,也就是采用接口隔离原则。
? 3)接口interface 1 中出现的方法,根据实际情况拆分为三个接口。
?
3、依赖倒置
定义
1)高层模块不应该依赖低层模块,二者都应该依赖其抽象
2)抽象不应该依赖细节,细节应该依赖抽象
3)依赖倒转(倒置)的中心思想是面向接口编程
4)依赖倒转原则是基于这样的设计理念,相对于细节的多变性,抽象的东西要稳定的多,以抽象为基础搭建的架构比以细节为基础的架构要稳定得多,在Java中,抽象指的是接口和抽象类,细节就是具体的实现类。
5)使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去实现。
应用实例
package com.itsmallstudent.principle.inversion;
public class DependencyInversion {
public static void main(String[] args) {
Person person = new Person();
person.receive(new Email());
}
}
class Email{
public String getInfo(){
return "hello world";
}
}
/**
* 1,完成了Person接受消息的功能
* 方式1分析
* 1.简单,比较容易想到
* 2.如果获取对象是微信等新增类,那么person类需要新增对应方法
* @author cpms
*
*/
class Person{
public void receive(Email email){
System.out.println(email.getInfo());
}
}
//使用依赖倒转原则
package com.itsmallstudent.principle.inversion;
public class DependencyInversion2 {
public static void main(String[] args) {
Person2 person = new Person2();
person.receive(new Phone());
person.receive(new WeChat());
System.out.println();
}
}
interface Msg{
String getInfo();
}
class Phone implements Msg{
@Override
public String getInfo() {
// TODO Auto-generated method stub
return "手机短信:Hello World";
}
}
class WeChat implements Msg{
@Override
public String getInfo() {
// TODO Auto-generated method stub
return "微信消息:Hello World";
}
}
class Person2{
public void receive(Msg msg){
System.out.println(msg.getInfo());
}
}
依赖关系传递的三种方式和案例
1)接口传递
interface Msg{
String getInfo();
}
interface Receicve{
String Receice(Msg msg);
}
class Person3 implements Receicve{
@Override
public String Receice(Msg msg) {
// TODO Auto-generated method stub
return msg.getInfo();
}
}
2)构造方法传递,setter方法传递
interface Msg{
String getInfo();
}
interface Receicve{
String Receice();
}
class Person3 implements Receicve{
private Msg yourMsg;
//构造方法
public Person3(Msg msg){
this.yourMsg=msg;
}
public Msg getYourMsg() {
return yourMsg;
}
//setter 方法
public void setYourMsg(Msg yourMsg) {
this.yourMsg = yourMsg;
}
@Override
public String Receice() {
// TODO Auto-generated method stub
return yourMsg.getInfo();
}
}
注意事项和细节
- 低层模块尽量都要有抽象类和接口,或者两者都有,程序的稳定性更好
- 变量的声明类型尽量是抽象类和接口,这样对我们的变量引用和实际对象间,就存在一个缓冲层,利于程序扩展和优化。
- 继承时遵循里氏替换原则。
4、里氏替换原则
基本介绍
- 如果对每个类型为T1的对象O1,都有类型为T2的对象O2,使得以T1定义的所有程序p在所有的对象O1都代换成O2时,程序p的行为没有变化,那么类型T2是类型T1的子类型。换句话说,所有引用基类的地方必须能透明地使用其子类的对象。
- 在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法。
- 里氏替换原则告诉我们,继承实际上让两个类耦合性增强了,在适当的情况下,可以通过聚合,组合,依赖来处理问题。
//创建一个更加基础的基类
class Basic{
//把更加基础的方法和成员写到basic中
}
//A类
class A extends Basic {
public int function1(int a,int b){
return a-b;
}
}
//B类
class B extends Basic{
//如果b想使用a的方法,使用组合关系
private A a = new A();
public int function1(int a, int b) {
// TODO Auto-generated method stub
return a+b;
}
public int function2(int a,int b){
return function1(a, b)+9;
}
//假如我们仍然想使用A的方法
public int function3(int a,int b){
return this.a.function1(a, b);
}
}
5、开闭原则
基本介绍
- 开闭原则是编程中最基础、最重要的设计原则
- 一个软件实体如类,模块和函数应该对拓展开放(对提供方),对修改关闭(对使用方),用抽象构建框架,用实现扩展细节。
- 当软件需要变化时,尽量通过拓展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
- 编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。
代码
package com.itsmallstudent.principle.ocp;
/**
* 优点是比较好理解,简单易操作
* 缺点是违反了设计模式的ocp原则,则对扩展开放,对修改关闭,即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码
* 比如我们这时要新增加一个图形种类,我们需要做如下修改,修改的地方比较多
* @author cpms
*
*/
public class Example {
public static void main(String[] args) {
//使用看看存在的问题
GraphicEditor graphicEditor = new GraphicEditor();
graphicEditor.drawRectangle(new Rectangle());
graphicEditor.drawCircle(new Circle());
}
}
//这是一个用于绘图的类
class GraphicEditor{
//接受shape对象
public void drawShape(Shape s){
if(s.my_type==1){
drawRectangle(s);
}else if(s.my_type==2) {
drawCircle(s);
}
}
//绘制矩形
public void drawRectangle(Shape r){
System.out.println("绘制矩形");
}
//绘制圆形
public void drawCircle(Shape r){
System.out.println("绘制圆形");
}
}
class Shape{
int my_type;
}
class Rectangle extends Shape{
Rectangle() {
super.my_type=1;
}
}
class Circle extends Shape{
public Circle() {
super.my_type=2;
}
}
改进的思路分析
? 思路:把创建Shape类做成抽象类,并提供一个抽象的draw方法,让子类去实现即可,这样我们有新的图形种类时,只需要让新的图形类继承Shape,并实现draw方法即可,
//这是一个用于绘图的类
class GraphicEditor1{
//接受shape对象
public void drawShape(Shape1 e){
e.darw();
}
}
abstract class Shape1{
int my_type;
abstract void darw();
}
class Rectangle2 extends Shape1{
public Rectangle2() {
// TODO Auto-generated constructor stub
super.my_type=1;
}
@Override
void darw() {
// TODO Auto-generated method stub
System.out.println("绘制矩形");
}
}
class Circle2 extends Shape1{
public Circle2() {
// TODO Auto-generated constructor stub
super.my_type=2;
}
@Override
void darw() {
// TODO Auto-generated method stub
System.out.println("绘制圆形");
}
}
6、迪米特原则
基本介绍
- 一个对象应该对其他对象保持最小的了解
- 类与类关系越密切,耦合度越大,
- 迪米特法则又叫最少知道原则,即一个类对自己依赖的类知道的越少越好,也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的pulic 方法,不对外暴露任何信息。
- 迪米特法则还有一个更简单的定义,只与直接的朋友通信。
- 直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这个两个对象之间是朋友关系。耦合的方法很多。依赖,关联,组合,聚合等,其中,我们称出现成员变量,方法参数,方法返回值中的类为直接的朋友,而出现再局部变量的类不是直接的朋友。也就是说,陌生的类最好不要以局部变量的形式出现在类的内部。
代码
package com.itsamllstudent.principle.demeter;
import java.util.ArrayList;
import java.util.List;
public class Demeter1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建了一个SchoolManager对象
SchoolManager schoolManager = new SchoolManager();
//
schoolManager.printAllEmployee(new CollegeManager());
}
}
//学校总部员工
class Employee{
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
//学院员工
class CollegeEmployee{
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
private String id;
}
//管理学院员工的管理类
class CollegeManager{
public List<CollegeEmployee> getAllEmployees(){
List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
for (int i = 0; i < 10; i++) {
CollegeEmployee employee = new CollegeEmployee();
employee.setId("学院员工id为"+i);
list.add(employee);
}
return list;
}
}
//学校的管理类
// 分析SchoolManger 类的直接朋友类有哪些,Employee,CollegeManager
// CollegeEmployee不是直接朋友,而是一个陌生类,这样违背了迪米特法则。
class SchoolManager{
public List<Employee> getAllEmployees(){
List<Employee> list = new ArrayList<Employee>();
for (int i = 0; i < 10; i++) {
Employee employee = new Employee();
employee.setId("学院总部员工id为"+i);
list.add(employee);
}
return list;
}
//分析问题
//1.CollegeEmployee不是SchoolManager的直接朋友
//2.CollegeEmployee是以局部变量方法出现在SchoolManager
//3.违反了迪米特法则
void printAllEmployee(CollegeManager sub){
List<CollegeEmployee> list = sub.getAllEmployees();
System.out.println("-----------分公司员工----------------");
for (CollegeEmployee e : list) {
System.out.println(e.getId());
}
List<Employee> list2 = this.getAllEmployees();
System.out.println("-----------学校总部员工------------------");
for (Employee employee : list2) {
System.out.println(employee.getId());
}
}
}
- 迪米特法则的核心是降低类之间的耦合
- 但是注意,由于每个类都减少了不必要的依赖,因此迪米特法则只是要求降低类间(对象间)耦合关系,并不是要求完全没有依赖关系
改进如下
package com.itsamllstudent.principle.demeter.improve;
import java.util.ArrayList;
import java.util.List;
public class ImproveDemeter1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建了一个SchoolManager对象
SchoolManager schoolManager = new SchoolManager();
//输出
schoolManager.printAllEmployee(new CollegeManager());
}
}
//学校总部员工
class Employee{
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
//学院员工
class CollegeEmployee{
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
private String id;
}
//管理学院员工的管理类
class CollegeManager{
public List<CollegeEmployee> getAllEmployees(){
List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
for (int i = 0; i < 10; i++) {
CollegeEmployee employee = new CollegeEmployee();
employee.setId("学院员工id为"+i);
list.add(employee);
}
return list;
}
//输出学院员工的信息
public void printEmployee() {
List<CollegeEmployee> list = this.getAllEmployees();
System.out.println("-----------分公司员工----------------");
for (CollegeEmployee e : list) {
System.out.println(e.getId());
}
}
}
//学校的管理类
class SchoolManager{
//
public List<Employee> getAllEmployees(){
List<Employee> list = new ArrayList<Employee>();
for (int i = 0; i < 10; i++) {
Employee employee = new Employee();
employee.setId("学院总部员工id为"+i);
list.add(employee);
}
return list;
}
void printAllEmployee(CollegeManager sub){
sub.printEmployee();
List<Employee> list2 = this.getAllEmployees();
System.out.println("-----------学校总部员工------------------");
for (Employee employee : list2) {
System.out.println(employee.getId());
}
}
}
7、合成复用原则
基本介绍
原则是尽量使用合成/聚合的方式,而不是使用继承
设计原则核心思想
- 找出应用中可能需要变化之处,把它们独立出来。不要和那些不需要变化的代码混在一起
- 针对接口编程,而不是针对实现编程。
- 为了交互对象之间的松耦合设计而努力
内容总结
以上是互联网集市为您收集整理的设计模式简介(一)全部内容,希望文章能够帮你解决设计模式简介(一)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。