设计模式学习笔记-基础知识篇

1. 设计模式的重要性

  1.1 设计模式解决的是在软件过程中如何来实现具体的软件功能。实现同一个功能的方法有很多,哪个设计容易扩展,容易复用,松耦合,可维护?设计模式指导我们找到最优方案。

  1.2 设计中往往会存在设计缺陷,这些缺陷包括:

    僵化性:难以对软件进行改动,即使在功能上来看是很小的改动

    脆弱性:在进行很小的改动时,可能导致很多地方出现问题

    顽固性:要把系统中某些通用的功能分离出来的努力和风险非常巨大

    粘滞性:当面临改动时,改动的方案有很多,一些会保持设计,一些会破坏设计,当采用保持设计的方法比用破坏设计的方法更难应付变化时,说明原设计具有较高的粘滞性

    晦涩性:模块难以理解

    不必要的重复:代码不能复用,往往通过Copy-Paste来实现相似功能

    不必要的复杂性:设计中包含了没有用的成分,往往是过度设计导致的

  1.3 如果你觉得在开发过程中发现以上问题(缺陷),那么就需要使用设计模式来改善最初设计,即重构原有的设计。如果你是最初的设计者,那么也需要应用设计模式来找到一个最优方案。设计模式不是编程语言,它修炼的是程序员的内功。因此,对于一个开发者来说,学习设计模式是非常必要的。

2. 对于初学者来说,必要的知识准备还是必须的,没有这些基础就很难将这些理解透彻。

  2.1 面向对象基本知识

  设计模式是面向对象编程的设计指导,因此学习设计模式前先要理解什么是面向对象,这里只简单列出了面向对象的主要概念,要是初学者的话还得查阅相关资料;对已经了解的老手来说,权当复习和梳理一下吧。

    2.1.1 面向对象三大特征:封装、继承、多态

    2.1.2 类与实例

    2.1.3 构造(析构)方法

    2.1.4 重载

    2.1.5 访问修饰符

    2.1.6 属性/字段/方法

    2.1.7 抽象类

    2.1.8 接口

  2.2 UML类图

  在学习设计模式时,通常接触到的只有类图,因此读懂UML类图对理解模式来说有很大帮助。下面来介绍UML类图中的关系    

  

    2.2.1 依赖关系(Dependency),用虚线加箭头表示。如上图动物(Animal)依赖空气(Air)。表示依赖关系的代码有以下几种

      1)作为参数

复制代码
        public class Air{public void GetOxygen() { Console.WriteLine("Get oxygen from air."); } } public abstract class Animal { /// <summary> /// 动物依赖空气才能呼吸,作为参数传入 /// </summary> /// <param name="air"></param> public void Breathe(Air air) { air.GetOxygen(); } }
复制代码

      2)在方法内部定义    

复制代码
            /// <summary>/// 动物依赖空气才能呼吸,在方法内部实例化新对象/// </summary> public void Breathe() { Air air = new Air(); air.GetOxygen(); }
复制代码

      3)静态方法调用

复制代码
            /// <summary>/// 在方法中调用静态方法/// </summary> public void Test() { ClassName.UseStaticMethode(); }
复制代码

    2.2.2 继承关系(Inherit),用实线加空心箭头表示,如上图鹰(Eagle)继承自动物(Animal)    

复制代码
        /// <summary>/// 鹰继承自Animal/// </summary> public class Eagle : Animal { }
复制代码

    2.2.3 实现关系(Realize),用虚线加空心箭头表示,如上图鹰(Eagle)实现了飞行能力(IFlyAble)    

复制代码
        /// <summary>/// 鹰继承自Animal/// </summary> public class Eagle : Animal, IFlyAble {         //实现IFlyAble接口中定义的方法 public void Fly() { Console.WriteLine("老鹰可以飞翔。"); } }
复制代码

    2.2.4 组合关系,讲组合关系之前不得不谈关联关系与聚合关系

      1)关联关系(Association):对于两个相对独立的对象,当一个对象实例与另一个对象的一些特定实例存在固定的对应关系时,这两个对象之间的关系为关联关系。例如:公司与员工的关系      

      

      代码表现,通过实例字段或属性来实现

复制代码
        public class Emplolyee{public string Name{ get; set; }}public class Company { /// <summary> /// 一个公司可以有多个员工 /// </summary> private Emplolyee[] employees; }
复制代码

      2) 聚合关系(Aggregate): 是关联关系的一种,是一种较强的关联关系,强调整体与部分之间的关系。例如:电脑与显示器的关系,就是整体与部分的关系,即聚合关系      

      

      代码表现,也是通过实例字段或属性来实现      

复制代码
        public class Displayer{/// <summary>/// 显示器型号 /// </summary> public string Model { get; set; } } public class Computer { /// <summary> /// 通过字段表示聚合关系 /// </summary> private Displayer displayer; }
复制代码

      3)组合关系,组合关系是聚合的一种特殊形式,表示一个所有物实例不能同时被两个所有物所拥有。如上例:鹰拥有一对翅膀,它的翅膀不能同时属于别的鹰。

      代码表现,也是通过实例字段或属性来实现      

复制代码
        public class Wing{}/// <summary>/// 鹰继承自Animal /// </summary> public class Eagle : Animal, IFlyAble { private Wing leftWing; private Wing rightWing; public Eagle() { // 在构造函数中实例化翅膀,防止翅膀被改变 leftWing = new Wing(); rightWing = new Wing(); } public void Fly() { Console.WriteLine("老鹰可以飞翔。"); } }
复制代码

      关联关系与聚合关系的区别: 关联关系所涉及的两个对象是处在同一个层次上的,比如程序员和计算机的关系就是一种关联关系,而不是聚合关系,因为程序员不是由计算机组成的。聚合关系涉 及的两个对象处于不平等的层次上,一个代表整体,一个代表部分。如计算机与显示器的关系就是聚集关系,因为显示器是计算机的一部分。

      聚合关系与组合关系的区别:聚合关系中处于被持有的对象,可以被别的对象所持有。如多态计算机可以共享同一个显示器。组合关系中被持有的对象只能被一个对象引用,不能共享给其它对象;而且被持有的对象的生命周期也由所有者控制,当所有者析构了,其所有物必须随着它一起析构。

转载于:https://www.cnblogs.com/fly1027/p/4866366.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/375487.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript对象类型详解

《JavaScript高级程序设计》已经学习到了第四章&#xff0c;不过因为第五章讲的都是各种对象类型&#xff0c;所以在进行第五章的学习之前&#xff0c;先深入了解一下对象是有好处的。 JavaScript Objects in Detail 关于对象类型的方方面面在这篇文章里都写得很清楚了&#xf…

旋转链表

给定一个链表&#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: 1->2->3->4->5->NULL, k 2输出: 4->5->1->2->3->NULL解释:向右旋转 1 步: 5->1->2->3->4->NULL向…

内心的平静就是财富本身-Cell组件-用友华表的由来-T君

时至今日&#xff0c;Cell组件仍是应用广泛的商业报表组件 作者&#xff1a;人生三毒 编者注&#xff1a;本文作者人生三毒为知名网站及网页游戏公司创始人&#xff0c;此前曾为IT类媒体资深编辑&#xff0c;见证了中国互联网早期的发展。 认识T君之前先认识的是他的软件&#…

mybatis06 增删改差 源码

user.java package cn.itcast.mybatis.po;import java.util.Date;public class User {private int id;private String username;// 用户姓名private String sex;// 性别private Date birthday;// 生日private String address;// 地址public int getId() {return id;}public voi…

socket 编程 基于 select 实现的回射客户端/服务程序

github 代码 地址 unp.h #include <stdio.h> #include <unistd.h> #include <arpa/inet.h> #include <string.h> #include <sys/socket.h> #include <stdlib.h> #include <errno.h> #include <sys/wait.h> #include <sys…

MyEclipse的优化

出自&#xff1a;http://blog.csdn.net/u010124571/article/details/41316255?refmyread 第一步: 取消自动validation validation有一堆&#xff0c;什么xml、jsp、jsf、js等等&#xff0c;我们没有必要全部都去自动校验一下&#xff0c;只是需要的时候才会手工校验一下&…

NSlog输出

NSLog的定义 void NSLog(NSString *format, …); 基本上&#xff0c;NSLog很像printf&#xff0c;同样会在console中输出显示结果。不同的是&#xff0c;传递进去的格式化字符是NSString的对象&#xff0c;而不是char *这种字符串指针。 实例 NSLog可以如下面的方法使用&#x…

推理题,会则秒解

你和你的朋友&#xff0c;两个人一起玩 Nim 游戏&#xff1a;桌子上有一堆石头&#xff0c;每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。 你们是聪明人&#xff0c;每一步都是最优解。 编写一个函数&#xff0c;来判断你是否可以在给定石头…

【图论】割点、桥、双连通

连通分量 个数可以通过一次BFS或者DFS得到 割点和桥 可以枚举删除每一个点或者每一条边&#xff0c;判断连通分量个数是否增加 更好的方法 该算法是R.Tarjan发明的。对图深度优先搜索&#xff0c;定义DFS(u)为u在搜索树&#xff08;以下简称为树&#xff09;中被遍历到的次序号…

奇酷手机显示Log

1、在桌面点击拨号&#xff0c;在拨号盘输入“*20121220#”&#xff0c;进入工程模式;2、看到日志输出等级&#xff0c;点进去 Log print enable 选 enable Java log level 选 LOGV C and C log level 选 LOGV Kernel log level 选 KERN_DEBUG3、完毕 参考网址&#xff1a;http…

getCanonicalPath getAbsolutePath区别

1、在winows环境下它们的区别是 &#xfeff;&#xfeff;getCanonicalPath是标准路径&#xff0c;没有特殊字符&#xff0c;getAbsolutePath是有特殊字符的 2、在AIX系统中它们的区别&#xff1a; 首先编译&#xff1a;javac com/ai/test/BugTest.java 然后运行&#xff1a;ja…

Hbase与hive整合

//hive与hbase整合create table lectrure.hbase_lecture10(sname string, score int) stored by org.apache.hadoop.hive.hbase.HBaseStorageHandler whth serdeproperties("hbase.columns.mapping" :key,cf1:score)tblproperties("hbase.table.name" &q…

C++实现一个http服务器

一个简单的博客后端服务器 github地址&#xff0c;持续更新 设计参考 #define MYSQLPP_MYSQL_HEADERS_BURIED #include "httplib.h" #include "rapidjson/document.h" #include <mysql/mysql.h> #include <iostream> #include <string>…

KMP算法的java实现

package com.trs.utils;public class KMPStr {/** 在KMP算法中&#xff0c;最难求的就是next函数&#xff0c;如何理解next函数是一个难题&#xff0c;特别是knext[k]&#xff0c;这里* 需要指出的是当p[i]!p[j]时&#xff0c;我们只有通过回溯将k的值逐渐减小&#xff0c;貌似…

线段分割法实现微信抢红包

无意间看到的一种实现抢红包的方法&#xff0c;于是用C实现了一下。 将一个红包分成 n 份 具体的思路是&#xff0c;将一个红包看作是一个线段&#xff0c;线段的长就是红包总金额&#xff0c;然后在这个线段上随机切 n-1 刀&#xff0c;分成 n 份&#xff0c;然后抢红包的人依…

JAVA多线程和并发基础面试问答(转载)

JAVA多线程和并发基础面试问答 原文链接&#xff1a;http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/ 多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里&#xff0c;从面试的角度列出了大部分重要的问题&#xff0c…

Linux的学习--crontab

之前了解过一点crontab&#xff0c;前段时间比较闲&#xff0c;就熟悉了一下&#xff0c;今天总结记录一下。 crontab命令常见于Unix和类Unix的操作系统之中&#xff0c;用于设置周期性被执行的指令。该命令从标准输入设备读取指令&#xff0c;并将其存放于"crontab"…

C++雪花算法实现

看来一下雪花算法的实现方法&#xff0c;用 c试着实现了一下&#xff0c;这里仅仅是实现了算法的流程&#xff0c;但是具体的细节&#xff0c;如并发、多线程访问等等没有具体考虑。 雪花算法的简单讲解参考 #include <sys/select.h> #include <iostream> #includ…

CAlayer层的属性

iOS开发UI篇—CAlayer层的属性 一、position和anchorPoint 1.简单介绍 CALayer有2个非常重要的属性&#xff1a;position和anchorPoint property CGPoint position; 用来设置CALayer在父层中的位置 以父层的左上角为原点(0, 0) property CGPoint anchorPoint; 称为“定位点”、…

Window Linux下实现指定目录内文件变更的监控方法

转自&#xff1a;http://qbaok.blog.163.com/blog/static/10129265201112302014782/ 对于监控指定目录内文件变更&#xff0c;window 系统提供了两个未公开API&#xff1a;SHChangeNotifyRegister SHChangeNotifyDeregister 分别用于注册Notify以及监视。 同时&#xff0c;还提…