当前位置:  编程技术>软件工程/软件设计
本页文章导读:
    ▪Singleton 考虑内存的释放和多线程      GOF的《设计模式》中这样描述:保证一个类仅有一个实例,并提供一个访问它的全局访问点。通常我们可以让一个全局变量使得一个对象被访问,但它不能阻止你实例化多个对象。一个最好的.........
    ▪大话设计模式之装饰者模式      装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。       利用组合(composition)和委托(delegation)可以在运行时具有继承行为的.........
    ▪input输入子系统源码部分函数分析      /* * 源文件目录: * /drivers/input/input.c */ 入口函数: static int __init input_init(void) 1、 err = class_register(&input_class); /* class设备节点生成 */ 2、 err = input_proc_init(); /* 为添加到pro.........

[1]Singleton 考虑内存的释放和多线程
    来源: 互联网  发布时间: 2013-11-19

GOF的《设计模式》中这样描述:保证一个类仅有一个实例,并提供一个访问它的全局访问点。通常我们可以让一个全局变量使得一个对象被访问,但它不能阻止你实例化多个对象。一个最好的办法是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。

也就是说,很多时候我们需要全局的对象,如一个工程中,数据库访问对象只有一个,这时,可以考虑使用单例模式。单例模式比全局对象好还包括:单例类可以继承,如下例。

单例模式的关键点在于:构造函数私有,静态的GetInstance。

另外,在C++中必须注意内存的释放。C++、Java、C#中还要注意多线程时的同步问题(下面的程序还没考虑多线程)。

#include <iostream>
using namespace std;

class Singleton {
private:
	Singleton() {} //①constructor declare private
	static Singleton* single; //③static member
public:
	static Singleton* getInstance() { //② static member function
		if(single == NULL)
			single = new Singleton();
		return single;
	}

	class Garbo {			//它的唯一工作就是在析构函数中删除
	public:
		~Garbo() {
			if(getInstance())
				delete getInstance();
		}

		static Garbo garbo; //// 定义一个静态成员,在程序结束时,系统会调用
		//它的析构函数,该析构函数会删除单例的唯一实例。
	};
	/*
	 * 考虑 memory leak 和 multithread(没有考虑)
	 *
	 *
	 * 使用这种方法释放C++单例模式对象有以下特征:
		在单例类内部定义专有的嵌套类Garbo。
		在单例类内定义私有的专门用于释放的静态成员。
		利用程序在结束时析构全局变量的特性,选择最终的释放时机。
		使用C++单例模式的代码不需要任何操作,不必关心对象的释放。*/

};

int main() {
	Singleton *s1 = Singleton::getInstance();
	Singleton *s2 = Singleton::getInstance();
	if(s1 == s2)
		cout << "Singleton is success";
}


作者:glx2012 发表于2013-4-8 10:45:55 原文链接
阅读:12 评论:0 查看评论

    
[2]大话设计模式之装饰者模式
    来源: 互联网  发布时间: 2013-11-19

装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

      利用组合(composition)和委托(delegation)可以在运行时具有继承行为的效果。通过动态的组合对象,可以在新的代码添加新功能,而无须改动现有代码。既然没有改动现有代码,那么引进bug或产生意外的副作用的机会将大幅度减少。

      利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能都利用组合的做法扩展对象的行为,既可以在运行时动态的进行扩展。



开闭原则:类应该对扩展开放,对修改关闭。代码应该如晚霞中的莲花一样的关闭(免于改变),如晨曦中的莲花一样的开放(能够扩展)。在遵循选择需要扩展的代码部分时要小心。每个地方都要采用开闭原则是一种浪费,也没有必要,通常会引入新的抽象层次,增加代码的复杂度,应该把注意力集中在设计中最有可能改变的地方。










   


//Beverage是一个抽象类,有两个方法getDescription()和cost()
public abstract class Beverage{
	String description="Unknown Beverage";
	
	//getDescription()已经在此实现了,但是cost必须在子类中实现。
	public String getDescription() {
		return description;
	}	
	public abstract double cost();
}


/*首先,必须让CondimentDecorator能够取代Beverage,所以将CondimentDecorator扩展为Beverage类。
所有的调料装饰者都必须重新实现getDescription()方法 */
public abstract class CondimentDecorator extends Beverage{
	public abstract String getDescription();
}

//写饮料的代码:
//首先,让Espresso(浓缩咖啡)扩展自Beverage类,因为是一种Espresso饮料。
public class Espresso extends Beverage{
	public Espresso(){
		//为了要设置饮料的描述,我们写了一个构造器。
		description="Espresso";
	}
	public double cost(){
		return 1.99;
	}
}


//写调料代码
//Mocha是一个装饰者,扩展自CondimentDecorator,CondimentDecorator扩展自Beverage
public class Mocha extends CondimentDecorator{
	Beverage beverage;
	/*要让Mocha能够引用一个Beverage,做法如下:
	  1、用一个实例变量记录饮料,也就是被装饰者。
	  2、想办法让被装饰着(饮料)被记录到实例变量中。如把饮料当做构造器的参数,再由构造器将此饮料记录在实例变量中。*/
	public Mocha(Beverage beverage){
		this.beverage=beverage;
	}
	//我们希望不只是描述饮料,而是完成的连调料也描述出来。所以,首先利用委托的办法,得到一个叙述,然后在其后面加上附加的叙述。
	public String getDescription(){
		return beverage.getDecription()+",Mocha";
	}
	//要计算带Mocha的饮料的价钱,首先把调用委托类给被装饰对象,以计算价钱,然后再加上Mocha的价钱,得到最后结果。
	public double cost(){
		return .20+beveragr.cost();
	}
}


//供应咖啡
public class StarbuzzCoffee{
	public static void main(String args[]){
		//定一杯Espresso,不需要调料,打印出它的描述与价钱。
		Beverage beverage=new Espresso();
		System.out.printIn(beverage.getDescription()+" $"+beverage.cost());
		//制造出一个DarkRoast对象,用Mocha装饰它,用第二个Mocha装饰它,用Whip装饰它。
		Beverage beverage2=new DarkRoast();
		beverage2=new Mocha(beverage2);
		beverage2=new Mocha(beverage2);
		beverage2=new Whip(beverage2);
		System.out.printIn(beverage2.getDescription()+" $"+beverage2.cost());
		//最后再来一杯调料味豆浆,摩卡,奶泡的HouseBlend咖啡。
		Beverage beverage3=new HouseBlend();
		beverage3=new Mocha(beverage3);
		beverage3=new Mocha(beverage3);
		beverage3=new Whip(beverage3);
		System.out.printIn(beverage3.getDescription()+" $"+beverage3.cost());
	}
}


 


作者:lantingxv_jing 发表于2013-4-8 21:29:05 原文链接
阅读:50 评论:1 查看评论

    
[3]input输入子系统源码部分函数分析
    来源: 互联网  发布时间: 2013-11-19
/*
 *	源文件目录:
 *			/drivers/input/input.c
 */

入口函数:
		static int __init input_init(void)
1、		err = class_register(&input_class);				/* class设备节点生成 */
2、             err = input_proc_init();			/* 为添加到proc文件系统的设备节点文件做一些初始化工作 */
3、	        err = register_chrdev(INPUT_MAJOR, "input", &input_fops);	/* 注册为字符型驱动 */


/*
 * input_fops结构体分析
 */
 static const struct file_operations input_fops = {
	.owner = THIS_MODULE,								/* 模块所属者 */
	.open = input_open_file,						/* 打开操作函数 */
	.llseek = noop_llseek,							/* 绕过llseek操作 */
};

/*
 * input_open_file函数分析 
 */
static int input_open_file(struct inode *inode, struct file *file)
		1. struct input_handler *handler;			/* handler声明 */
/*
 * input_hanler结构体:
 * struct input_handler {

		void *private;

		void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
		bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
		bool (*match)(struct input_handler *handler, struct input_dev *dev);
		int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
		void (*disconnect)(struct input_handle *handle);
		void (*start)(struct input_handle *handle);

		const struct file_operations *fops;
		int minor;
		const char *name;

		const struct input_device_id *id_table;
	
 *	struct list_head	h_list;
 *	struct list_head	node;
 *	};
 */
 		2. const struct file_operations *old_fops, *new_fops = NULL;		/* file_operations结构体声明 */
 		3. err = mutex_lock_interruptible(&input_mutex);			/* 上互斥锁操作 */
 		4. handler = input_table[iminor(inode) >> 5];				/* input_table链表中第iminor(inode) >> 5节点的handler */
 		5. if (handler)								/* 是否存在此handler */		
		new_fops = fops_get(handler->fops);			/* 存在内容则取出此handler的fops结构体赋予new_fops */
 		6. mutex_unlock(&input_mutex);					/* 解除互斥锁 */ 
 		7. 	old_fops = file->f_op;
				file->f_op = new_fops;				/* 交换file_operation,使input设备可使用相应的操作函数 */
		8. err = new_fops->open(inode, file);				/* 使用对于的打开函数 */
		9. fops_put(old_fops);							/* 释放old_fops */
		
/*
 *  input_register_device函数分析
 */
int input_register_device(struct input_dev *dev);
		1. static atomic_t input_no = ATOMIC_INIT(0);				/* 原子变量初始化 */
		2. struct input_handler *handler;					/* 新handler声明 */
		3. /* Every input device generates EV_SYN/SYN_REPORT events. */		/* 设置dev结构体 */
			 __set_bit(EV_SYN, dev->evbit);
			 /* KEY_RESERVED is not supposed to be transmitted to userspace. */
			 __clear_bit(KEY_RESERVED, dev->keybit);
			 /* Make sure that bitmasks not mentioned in dev->evbit are clean. */
			 input_cleanse_bitmasks(dev);
		4. init_timer(&dev->timer);					/* 初始化一个定时器 */
		5. error = device_add(&dev->dev);					/* 添加设备 */
			/*
			 *	device_add函数分析
			 */
			int device_add(struct device *dev)
				 	1. dev = get_device(dev);																								/* 获取dev的kobj */
				 	struct device *get_device(struct device *dev);
				 			\--->return dev ? to_dev(kobject_get(&dev->kobj)) : NULL;
				 	2. parent = get_device(dev->parent);		/* 获取父类驱动的kobj */
							 setup_parent(dev, parent);			/* 启动父类驱动 */
					3. error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);/* 将dev->kobj, dev->kobj.parent添加至内核中 */
						 
		6. error = mutex_lock_interruptible(&input_mutex);						/* 上互斥锁 */
		7. list_add_tail(&dev->node, &input_dev_list);							/* 添加到input_dev_list队列中 */
		8. list_for_each_entry(handler, &input_handler_list, node)
			input_attach_handler(dev, handler);		/* 遍历每个节点 */
		9. input_wakeup_procfs_readers();					/* 唤醒procfs_readers */
10. mutex_unlock(&input_mutex);								/* 解除互斥锁 */
	 
/*
 * input_register_handler函数分析 
 */	
int input_register_handler(struct input_handler *handler);
		1. struct input_dev *dev;							/* input_dev结构体指针声明 */
		2. retval = mutex_lock_interruptible(&input_mutex);					/* 上互斥锁 */
		3. INIT_LIST_HEAD(&handler->h_list);							/* 初始化list的前级与后继指针都指向list */
		4. if (handler->fops != NULL) {								/* 判断是否有值handler->fops */
			if (input_table[handler->minor >> 5]) {					/* 判断input_table[handler->minor >> 5]节点是否有值 */
				retval = -EBUSY;
				goto out;
			}
			input_table[handler->minor >> 5] = handler;			/* 将handler添加到input_table[handler->minor >> 5]节点上 */
		}
		5. list_add_tail(&handler->node, &input_handler_list);			/* 将handler->node放入到队列中 */
		6. list_for_each_entry(dev, &input_dev_list, node)
				input_attach_handler(dev, handler);			/* 遍历每个节点 */
		7. input_wakeup_procfs_readers();					/* 唤醒procfs_readers */

/*
 * input_allocate_device函数分析 
 */
struct input_dev *input_allocate_device(void);
 		1. struct input_dev *dev;						/* input_dev结构体声明 */
 		2. dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);			/* input_dev结构体空间分配 */
 			 /* 
 			  * 分析kzalloc函数
 			  */
 			  static inline void *kzalloc(size_t size, gfp_t flags)
 			  					\-->return kmalloc(size, flags | __GFP_ZERO);
 		3. if (dev) {								/* 初始化dev的成员变量 */	
				dev->dev.type = &input_dev_type;
				dev->dev.class = &input_class;
				device_initialize(&dev->dev);
				/*
				 * device_initialize函数
				 */
				 void device_initialize(struct device *dev)
					{
						dev->kobj.kset = devices_kset;
						kobject_init(&dev->kobj, &device_ktype);
						INIT_LIST_HEAD(&dev->dma_pools);
						mutex_init(&dev->mutex);
						lockdep_set_novalidate_class(&dev->mutex);
						spin_lock_init(&dev->devres_lock);
						INIT_LIST_HEAD(&dev->devres_head);
						device_pm_init(dev);
						set_dev_node(dev, -1);
					}
				/*
				 * 互斥锁初始化 
				 */
				mutex_init(&dev->mutex);
				/*
				 * 自旋锁初始化
				 */
				spin_lock_init(&dev->event_lock);
				INIT_LIST_HEAD(&dev->h_list);
				INIT_LIST_HEAD(&dev->node);
		
				__module_get(THIS_MODULE);
			}

/*
 * input_attach_handler函数分析 
 */
static int input_attach_handler(struct input_dev *dev, struct input_handler *handler);
		1. id = input_match_device(handler, dev);					/* 比较handler与dev的id */
		2. error = handler->connect(handler, dev, id);					/* 调用相应handler的connet函数 */
		
/*
 * input_register_handle函数分析 
 */
int input_register_handle(struct input_handle *handle)
		1. error = mutex_lock_interruptible(&dev->mutex);				/* 上互斥锁 */
		2. if (handler->filter)								/* 使dev->h_list指向handle->d_node */
			list_add_rcu(&handle->d_node, &dev->h_list);
		   else
				list_add_tail_rcu(&handle->d_node, &dev->h_list);
		3. mutex_unlock(&dev->mutex);						/* 解除互斥锁 */1
		4. list_add_tail_rcu(&handle->h_node, &handler->h_list);	/* 使handler->h_list指向handle->h_node */	

作者:toraloo 发表于2013-4-9 15:28:36 原文链接
阅读:38 评论:0 查看评论

    
最新技术文章:
▪主-主数据库系统架构    ▪java.lang.UnsupportedClassVersionError: Bad version number i...    ▪eclipse项目出现红色叉叉解决方案
▪Play!framework 项目部署到Tomcat    ▪dedecms如何做中英文网站?    ▪Spring Batch Framework– introduction chapter(上)
▪第三章 AOP 基于@AspectJ的AOP    ▪基于插件的服务集成方式    ▪Online Coding开发模式 (通过在线配置实现一个表...
▪观察者模式(Observer)    ▪工厂模式 - 程序实现(java)    ▪几种web并行化编程实现
▪机器学习理论与实战(二)决策树    ▪Hibernate(四)——全面解析一对多关联映射    ▪我所理解的设计模式(C++实现)——解释器模...
▪利用规则引擎打造轻量级的面向服务编程模式...    ▪google blink的设计计划: Out-of-Progress iframes    ▪FS SIP呼叫的消息线程和状态机线程
▪XML FREESWITCH APPLICATION 实现    ▪Drupal 实战    ▪Blink: Chromium的新渲染引擎
▪(十四)桥接模式详解(都市异能版)    ▪你不知道的Eclipse用法:使用Allocation tracker跟...    ▪Linux内核-进程
▪你不知道的Eclipse用法:使用Metrics 测量复杂度    ▪IT行业为什么没有进度    ▪Exchange Server 2010/2013三种不同的故障转移
▪第二章 IoC Spring自动扫描和管理Bean    ▪CMMI简介    ▪目标检测(Object Detection)原理与实现(六)
▪值班总结(1)——探讨sql语句的执行机制    ▪第二章 IoC Annotation注入    ▪CentOS 6.4下安装Vagrant
▪Java NIO框架Netty1简单发送接受    ▪漫画研发之八:会吃的孩子有奶吃    ▪比较ASP和ASP.NET
▪SPRING中的CONTEXTLOADERLISTENER    ▪在Nginx下对网站进行密码保护    ▪Hibernate从入门到精通(五)一对一单向关联映...
▪.NET领域驱动设计—初尝(三:穿过迷雾走向光...    ▪linux下的块设备驱动(一)    ▪Modem项目工作总结
▪工作流--JBPM简介及开发环境搭建    ▪工作流--JBPM核心服务及表结构    ▪Eclipse:使用JDepend 进行依赖项检查
▪windows下用putty上传文件到远程Linux方法    ▪iBatis和Hibernate的5点区别    ▪基于学习的Indexing算法
▪设计模式11---设计模式之中介者模式(Mediator...    ▪带你走进EJB--JMS编程模型    ▪从抽象谈起(二):观察者模式与回调
▪设计模式09---设计模式之生成器模式(Builder)也...    ▪svn_resin_持续优化中    ▪Bitmap recycle方法与制作Bitmap的内存缓存
▪Hibernate从入门到精通(四)基本映射    ▪设计模式10---设计模式之原型模式(Prototype)    ▪Dreamer 3.0 支持json、xml、文件上传
▪Eclipse:使用PMD预先检测错误    ▪Jspx.net Framework 5.1 发布    ▪从抽象谈起(一):工厂模式与策略模式
▪Eclipse:使用CheckStyle实施编码标准    ▪【论文阅读】《Chain Replication for Supporting High T...    ▪Struts2 Path_路径问题
▪spring 配置文件详解    ▪Struts2第一个工程helloStruts极其基本配置    ▪Python学习入门基础教程(learning Python)--2 Python简...
▪maven springmvc环境配置    ▪基于SCRUM的金融软件开发项目    ▪software quality assurance 常见问题收录
▪Redis集群明细文档    ▪Dreamer 框架 比Struts2 更加灵活    ▪Maven POM入门
▪git 分支篇-----不断更新中    ▪Oracle非主键自增长    ▪php设计模式——UML类图
▪Matlab,Visio等生成的图片的字体嵌入问题解决...    ▪用Darwin和live555实现的直播框架    ▪学习ORM框架—hibernate(二):由hibernate接口谈...
▪(十)装饰器模式详解(与IO不解的情缘)    ▪无锁编程:最简单例子    ▪【虚拟化实战】网络设计之四Teaming
▪OSGi:生命周期层    ▪Javascript/Jquery——简单定时器    ▪java代码 发送GET、POST请求
▪Entity Framework底层操作封装(3)    ▪HttpClient 发送GET、POST请求    ▪使用spring框架,应用启动时,加载数据
▪Linux下Apache网站目录读写权限的设置    ▪单键模式的C++描述    ▪学习ORM框架—hibernate(一):初识hibernate
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3