论坛首页 Java企业应用论坛

炮灰:几个设计模式理解1

浏览 6857 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (2) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-01-13  
几个模式的简单理解,作为炮灰大家轰一轰,看有没有理解错的地方,帮补充补充!

1、代理模式:要求委托第三方来做,要求代理类和被代理类有同样的功能,代理类必须知道代理类有什么功能,他能做些什么事,这就要求统一接口。
2、策略模式:定义三个策略,如果策略相似,请注意统一接口,之后要定义场景,场景提供设置策略方法,执行策略方法。
3、单例模式:方法大部分是private的(只有内部访问),getInstance是static,为了避免多线程,使用synchronized。
4、多例模式:创建多个实例,类似于某个java包下的所有类,都创建实例(for example:一个朝代多个皇帝)。
5、适配器模式:个人认为目的是对一个事物的不同的两个类(A、B)的描述(因为可能是不同系统),为了使用两个类统一,首先使用统一接口,定义个类(适配器,将类重新改造、整合重组)继承B,将原有的信息重组为接口的统一信息。
***接口为了方便可以就把A抽象成接口,当然也可根据具体需求情况自己定义。
6、门面模式:对client端不透明,高内聚松耦合,定义接口,具体动作实现类,门户类,对于门户类可以设置实现类的动作执行顺序等,对client端提供执行的接口。
7、建造者模式:定义建造模式类,建造实现类(设置模式类是如何实现的,例如顺序用List设置等)。可以实现更多级别的实现。
8、原型模式:个人认为,利用原来的原型,创建和原来关系密切,没有太大变化的新类,经常利用Object的cloneable(),复制原型,注意这是浅复制,理解浅复制和深复制[size=medium][/size]。
   发表时间:2010-01-14  

啊? 好像全部都不对呀:) 首先模式是一种思想(如果理解了,请仅仅把它当成词汇,方便交流)

1. 代理模式

引用

要求委托第三方来做,要求代理类和被代理类有同样的功能,代理类必须知道代理类有什么功能


不正确。



而是为对象提供一种代理,以控制一个对象的仿问, 至于做什么没关系,可能做完全不同的事。

对于客户来说(使用这个对象的客户)是透明的, 他不关心也不需要知道操作的是原对象还是代理对象。

   比方说你有一个访问数据库的耗时操作 DAO, 他是直接操作数据库的, 你需要实现缓存, 你可以实现一个 CachedDAO.

interface IDAO {
	Object getData(String key);
}

class DAO implements IDAO {
	public Object getData(String key) {
		Object o = ...// read from database that consume time.
		return o;
	}
}

class CachedDAO implements IDAO {
	public Object getData(String key) {
		Object o = // 在缓存中先看看
		if (o == null) {
			o = dao.getData(key);	// 这时候仿问真实的DAO对象
		}
		return o;
	}
}

class Client {
	public void useDAO(IDAO dao) {
		Object o = dao.getData("abc"); // 可能来自代理哦, Client并不知道
	}
}



2. 策略模式

主要用于封装算法, 使得算法可以独立于客户而变化。

3. 单例模式

 

写道
方法大部分是private的(只有内部访问),getInstance是static,为了避免多线程,使用synchronized。

 

前半部分:错误!

 

 单例模式(Singleton) : 保证一个类仅有一个实例, 并提供一个访问它的全局访问点。

 

后半部分没说清楚:

 

楼主想说的应该是: 延迟初始化, 在多线程环境下,需要考虑线程安全。 

 

 可以采用 synchronized 在方法上同步, 也可以 double check 在方法内进行同步。也可以像下面这样(很简洁, 也不需要同步,由JAVA类载入器来保证线程安全)

 

public class Sington {   
	   
    private static class SingtonHolder {       
        public static Sington INSTANCE = new Sington();   
    }   
       
    public static Sington getInstance() {   
        return SingtonHolder.INSTANCE;   
    }   
       
    private Sington() { }   
   
}   

 

多例模式:

 

没听说过。 Flyweight? 还是 Prototype?

 

 


适配器

 

 

写道
个人认为目的是对一个事物的不同的两个类(A、B)的描述(因为可能是不同系统),为了使用两个类统一,首先使用统一接口,定义个类(适配器,将类重新改造、整合重组)继承B,将原有的信息重组为接口的统一信息。

 

可能你理解了,但表达不清。

 

适配器就是适配作用, 比如系统要用一个类,比如需要排序。

 

interface Sorter {
	void sort(int[] a);
}

class Client {
	public void use(Sorter sorter) {
		// ..
	}
}

 

 

但是你刚好有一个类, 他完成了复杂的排序(尽管对数组的排序并不复杂), 但是他是这样的

 

class MySorter() {
	
	public void quickSort(int[] a) {
		//
	}
}

 

方法签名不对,即使对也用不上(因为没有实现Sorter接口)

 

所以你要配接它:

 

class MySorterAdapter implements Sorter {
	private MySorter sorter;
	public MySorterAdapter(MySorter sorter) {
		this.sorter = sorter;
	}
	public void sort(int[] a) {
		sorter.quickSort(a);
	}
}

 

这时候就可以通过 MySorterAdapter ,在Client 环境下,使用 MySorter类了。

 

 

门面模式

 

写道
对client端不透明,高内聚松耦合,定义接口,具体动作实现类,门户类,对于门户类可以设置实现类的动作执行顺序等,对client端提供执行的接口。

 

 

Facade: ....

假设你有一个复杂的系统,很复杂呀, 文档像牛津大字典一样厚。

然后你的老板叫你开发一个新的系统,配合这个系统用, 新的系统仅仅用到了这个系统的一部分,比如用户资料。

新系统由五个人开发。

然后你只要分配出一个人, 研究一下那个牛津字典的一小部分, 先写一个Facade,  用于“读” “写” 用户资料。 其他的部分不用管他。

然后你的新系统就通过这个“窗口”, 你的其他成员不需要去了解那个复杂系统, 只要使用这个接口 就成。

建造者模式

Builder?

原型模式:

个人认为,利用原来的原型,创建和原来关系密切,没有太大变化的新类,经常利用Object的cloneable(),复制原型,注意这是浅复制,理解浅复制和深复制[size=medium][/size]。 

 

5555555, 前面半句话还有一点点那个味道,后来就离题了。 

 

假设你写一个文档程序, 里面有一个表单,功能是“从该文件新建”

你不是重头来, 你是从当前的文档复制一份,再在上面修改。

然后你可以这样:

Document newDoc =  new Document();

newDoc.setTitle(doc.getTitle());

newDoc.setA(doc.getA());

newDoc.setB(doc.getB());

...很多很多属性

其实这个任何可以交给Document, 在Docuemnt类里完成, 类里面可能代码比较复杂,但他不会弄漏,而且清楚复制哪些属性

这里只要:

Document newDoc = doc.clone();

//

楼主如果初接触模式,可以先不要看《设计模式》这本书,可以先看 《设计模式解析》 或 《Head First Design Pattern》 或者 Bob大叔的《敏捷软件开发,原则,模式与实践》。

0 请登录后投票
   发表时间:2010-01-15  
这两天 刚刚开始接触设计模式,刚刚看了一个视频里面的工厂模式。看上去跟lz说的一个都对不上呢?不会是我还没有理解到位吧。
0 请登录后投票
   发表时间:2010-01-15  
实践出真理啊。
我也对23种设计模式做过学习,但是很多讲的虽然明白,但是在实际运用中还是模棱两可的,好多模式都有相似点。没有点实际开发经验感觉很难理解的。
    比如代理模式,最主要的远程代理,如果没实际经验的不知所云。完全迷茫的。
    感觉还是在实际中遇到问题,仔细思考后,再映射到设计模式上,这样理解起来更透彻。
   
0 请登录后投票
   发表时间:2010-01-15   最后修改:2010-01-15
habzyhs 写道
这两天 刚刚开始接触设计模式,刚刚看了一个视频里面的工厂模式。看上去跟lz说的一个都对不上呢?不会是我还没有理解到位吧。

我没说工厂模式啊,最近也是刚刚研究,学习阶段,很多理解不到位,所以要先当“炮灰”啊!哈哈
0 请登录后投票
   发表时间:2010-01-15  
lujiawu12 写道
实践出真理啊。
我也对23种设计模式做过学习,但是很多讲的虽然明白,但是在实际运用中还是模棱两可的,好多模式都有相似点。没有点实际开发经验感觉很难理解的。
    比如代理模式,最主要的远程代理,如果没实际经验的不知所云。完全迷茫的。
    感觉还是在实际中遇到问题,仔细思考后,再映射到设计模式上,这样理解起来更透彻。
   


是啊,我也是这么想的,但感觉还得先学学,要不然用到了都不知道!先学学理论,争取能多理解点,实际中用到了在深入理解吧!
0 请登录后投票
   发表时间:2010-01-15  
bencode 写道

啊? 好像全部都不对呀:) 首先模式是一种思想(如果理解了,请仅仅把它当成词汇,方便交流)

1. 代理模式

引用

要求委托第三方来做,要求代理类和被代理类有同样的功能,代理类必须知道代理类有什么功能


不正确。



而是为对象提供一种代理,以控制一个对象的仿问, 至于做什么没关系,可能做完全不同的事。

对于客户来说(使用这个对象的客户)是透明的, 他不关心也不需要知道操作的是原对象还是代理对象。

   比方说你有一个访问数据库的耗时操作 DAO, 他是直接操作数据库的, 你需要实现缓存, 你可以实现一个 CachedDAO.

interface IDAO { Object getData(String key); } class DAO implements IDAO { public Object getData(String key) { Object o = ...// read from database that consume time. return o; } } class CachedDAO implements IDAO { public Object getData(String key) { Object o = // 在缓存中先看看 if (o == null) { o = dao.getData(key); // 这时候仿问真实的DAO对象 } return o; } } class Client { public void useDAO(IDAO dao) { Object o = dao.getData("abc"); // 可能来自代理哦, Client并不知道 } }



2. 策略模式

主要用于封装算法, 使得算法可以独立于客户而变化。

3. 单例模式

 

写道
方法大部分是private的(只有内部访问),getInstance是static,为了避免多线程,使用synchronized。

 

前半部分:错误!

 

 单例模式(Singleton) : 保证一个类仅有一个实例, 并提供一个访问它的全局访问点。

 

后半部分没说清楚:

 

楼主想说的应该是: 延迟初始化, 在多线程环境下,需要考虑线程安全。 

 

 可以采用 synchronized 在方法上同步, 也可以 double check 在方法内进行同步。也可以像下面这样(很简洁, 也不需要同步,由JAVA类载入器来保证线程安全)

 

public class Sington { private static class SingtonHolder { public static Sington INSTANCE = new Sington(); } public static Sington getInstance() { return SingtonHolder.INSTANCE; } private Sington() { } }

 

多例模式:

 

没听说过。 Flyweight? 还是 Prototype?

 

 


适配器

 

 

写道
个人认为目的是对一个事物的不同的两个类(A、B)的描述(因为可能是不同系统),为了使用两个类统一,首先使用统一接口,定义个类(适配器,将类重新改造、整合重组)继承B,将原有的信息重组为接口的统一信息。

 

可能你理解了,但表达不清。

 

适配器就是适配作用, 比如系统要用一个类,比如需要排序。

 

interface Sorter { void sort(int[] a); } class Client { public void use(Sorter sorter) { // .. } }

 

 

但是你刚好有一个类, 他完成了复杂的排序(尽管对数组的排序并不复杂), 但是他是这样的

 

class MySorter() { public void quickSort(int[] a) { // } }

 

方法签名不对,即使对也用不上(因为没有实现Sorter接口)

 

所以你要配接它:

 

class MySorterAdapter implements Sorter { private MySorter sorter; public MySorterAdapter(MySorter sorter) { this.sorter = sorter; } public void sort(int[] a) { sorter.quickSort(a); } }

 

这时候就可以通过 MySorterAdapter ,在Client 环境下,使用 MySorter类了。

 

 

门面模式

 

写道
对client端不透明,高内聚松耦合,定义接口,具体动作实现类,门户类,对于门户类可以设置实现类的动作执行顺序等,对client端提供执行的接口。

 

 

Facade: ....

假设你有一个复杂的系统,很复杂呀, 文档像牛津大字典一样厚。

 

然后你的老板叫你开发一个新的系统,配合这个系统用, 新的系统仅仅用到了这个系统的一部分,比如用户资料。

 

新系统由五个人开发。

 

然后你只要分配出一个人, 研究一下那个牛津字典的一小部分, 先写一个Facade,  用于“读” “写” 用户资料。 其他的部分不用管他。

然后你的新系统就通过这个“窗口”, 你的其他成员不需要去了解那个复杂系统, 只要使用这个接口 就成。

建造者模式

Builder?

原型模式:

个人认为,利用原来的原型,创建和原来关系密切,没有太大变化的新类,经常利用Object的cloneable(),复制原型,注意这是浅复制,理解浅复制和深复制[size=medium][/size]。


 

5555555, 前面半句话还有一点点那个味道,后来就离题了。 

 

假设你写一个文档程序, 里面有一个表单,功能是“从该文件新建”

你不是重头来, 你是从当前的文档复制一份,再在上面修改。

然后你可以这样:

Document newDoc =  new Document();

newDoc.setTitle(doc.getTitle());

newDoc.setA(doc.getA());

newDoc.setB(doc.getB());

...很多很多属性

其实这个任何可以交给Document, 在Docuemnt类里完成, 类里面可能代码比较复杂,但他不会弄漏,而且清楚复制哪些属性

这里只要:

Document newDoc = doc.clone();

//

楼主如果初接触模式,可以先不要看《设计模式》这本书,可以先看 《设计模式解析》 或 《Head First Design Pattern》 或者 Bob大叔的《敏捷软件开发,原则,模式与实践》。


Object.clone(); 像这种模式是浅复制,如果某个属性是类的话,和原来对象是共享的!我只是想做个标志,怕忘啦!

有些地方确实理解的不到位,非常感谢。十足的炮灰哦!

0 请登录后投票
   发表时间:2010-01-15  
hell_liul 写道
lujiawu12 写道
实践出真理啊。
我也对23种设计模式做过学习,但是很多讲的虽然明白,但是在实际运用中还是模棱两可的,好多模式都有相似点。没有点实际开发经验感觉很难理解的。
    比如代理模式,最主要的远程代理,如果没实际经验的不知所云。完全迷茫的。
    感觉还是在实际中遇到问题,仔细思考后,再映射到设计模式上,这样理解起来更透彻。
   


是啊,我也是这么想的,但感觉还得先学学,要不然用到了都不知道!先学学理论,争取能多理解点,实际中用到了在深入理解吧!

 

其实最重要的是掌握面向对象设计的基本原理,然后去理解这些模式就会很自然。

 

比较重要的类设计原则有: 

SRP, 单一职责原则, 一个类应该只有一个引起它变化的原因

OCP, 开放封闭原则, 类,函数,或模块应该是可以扩展的,但是不可以修改的

DIP,依赖倒置原则 , 应该依赖于抽像, 而不应该依赖于细节, 特别是,抽像不应该依赖于细节

LSP Liskou替换原则 ,子类应该能够替换父类, 而不是仅仅为了重用去继承

ISP, 接口隔层原则, 接口不属于实现者,它更属于客户。

 

 

可以从模式中去掌握这些基本设计原则, 所以蕴涵在设计模式中的原理比模式本身的表现出的类结构层次结构,关系最重要的。

 

 

0 请登录后投票
   发表时间:2010-01-15  
bencode 写道

其实最重要的是掌握面向对象设计的基本原理,然后去理解这些模式就会很自然。

 

比较重要的类设计原则有: 

SRP, 单一职责原则, 一个类应该只有一个引起它变化的原因

OCP, 开放封闭原则, 类,函数,或模块应该是可以扩展的,但是不可以修改的

DIP,依赖倒置原则 , 应该依赖于抽像, 而不应该依赖于细节, 特别是,抽像不应该依赖于细节

LSP Liskou替换原则 ,子类应该能够替换父类, 而不是仅仅为了重用去继承

ISP, 接口隔层原则, 接口不属于实现者,它更属于客户。

 

 

可以从模式中去掌握这些基本设计原则, 所以蕴涵在设计模式中的原理比模式本身的表现出的类结构层次结构,关系最重要的。

 

 


哦,看来还有好多东西要看啊!以前外包了,刚刚转过来,路还很长啊!

0 请登录后投票
   发表时间:2010-01-15  
感觉2楼给的代理模式有误导的倾向
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics