JiveJdon Community Forums
在线133人 Home | 论坛 | 培训咨询 | 精华 | 查搜 | 注册 | 登陆 |
首页 » 论坛 » J2EE/JavaEE/JEE/EJB/JSF等技术讨论
???en_US.forumThreadPrev.name??? 上一主题
Go back to the topic listing   返回主题列表
???en_US.forumThreadNext.name??? 下一主题
这个主题共有 24 回复 / 2 页 [ 1 2 下一页 ]  发表新帖子  回复该主题贴
tellhow

发表文章: 13
注册时间: 2007年04月09日 13:48
给他发消息
求教设计模式之Adapter(适配器)的问题 发表: 2007年04月09日 14:16 回复
http://www.jdon.com/designpatterns/adapter.htm
现在有一个应用,需要既打方形桩,又打圆形桩.那么我们需要将这两个没有关系的类综合应用.假设RoundPeg我们没有源代码,或源代码我们不想修改,那么我们使用Adapter来实现这个应用:

public class PegAdapter extends SquarePeg{

  private RoundPeg roundPeg;

  public PegAdapter(RoundPeg peg)(this.roundPeg=peg;)

  public void insert(String str){ roundPeg.insertIntoHole(str);}

}

代码中PegAdapter类继承了SquarePeg类,
并重载了父类insert()方法.
可以实现打圆形桩,但如果要打方形桩,该如何实现呢?
请banq大虾不吝赐教!
banq

发表文章: 9114
注册时间: 2002年08月03日 17:08
给他发消息
回复:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月09日 16:41 回复
>可以实现打圆形桩,但如果要打方形桩,该如何实现呢?

要打方形桩参考打圆形桩方式.

设计模式和代码展现的是一种模式和方式,可以重用的.
tellhow

发表文章: 13
注册时间: 2007年04月09日 13:48
给他发消息
re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月10日 10:26 回复
首先感谢banq大虾的回复!
我是菜鸟,对Adapter(适配器)也不太理解,如果提出幼稚的问题,还请大虾耐心教导!
我对Adapter(适配器)的理解:
将两个不兼容的类纠合在一起使用,并实现这两个不兼容类的功能.(这两个类对我们是透明的,我们只知道其方法而不知道其代码.)
public class PegAdapter extends SquarePeg{

  private RoundPeg roundPeg;

  public PegAdapter(RoundPeg peg)(this.roundPeg=peg;)

  public void insert(String str){ roundPeg.insertIntoHole(str);}

}
PegAdapter类虽然继承了SquarePeg类,但insert()方法被重载了.
PegAdapter p=new PegAdapter(peg);
p.insert(str);//打圆形桩
PegAdapter类能实现打圆形桩的功能,打方形桩的功能却不知道如何实现了.

我对代码做了如下修改:
public class PegAdapter extends SquarePeg{

  private RoundPeg roundPeg;

  public PegAdapter(RoundPeg peg)(this.roundPeg=peg;)

  public void insertIntoHole(String str){ roundPeg.insertIntoHole(str);}

}

PegAdapter类不重载insert()方法.
PegAdapter p=new PegAdapter(peg);
p.insert(str);//打方形桩
p.insertIntoHole(str);//打圆形桩
这样一来,PegAdapter类既能实现打圆形桩的功能,也能实现打方形桩的功能了.

有什么不对的地方,还请banq大虾指出,谢了!
power1128

发表文章: 52
注册时间: 2006年05月24日 14:37
给他发消息
回复:re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月15日 13:14 回复
我是这样理解的,作者的意思是,现在有一个打方形桩的系统,比如叫SquareClient,它可能会调用SquarePeg的insert()方法,这个SquareClient和SquarePeg是我们已经有的系统,现在出现了另一个RoundPeg类,我们希望SquareClient也能操作它,并且不用修改代码。我们引入adapter,注意PegAdapter extends SquarePeg,也就是说PegAdapter是SquarePeg的子类,这样我们的SquareClient就能透明的操作这个类了,比如:

//用圆形桩对象为参数,构造adapter
PegAdapter square = new PegAdapter(roundObject);
SquareClient client = new SquareClient();
client.setPeg(square);
//客户端不用修改,同样是调用insert,实际上是调用方形桩的insertIntoHole
client.insert();
tellhow

发表文章: 13
注册时间: 2007年04月09日 13:48
给他发消息
re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月16日 11:14 回复
首先感谢power1128大哥的回复!
看完回复我似乎明白了点!

//用圆形桩对象为参数,构造adapter
PegAdapter square = new PegAdapter(roundObject);
SquareClient client = new SquareClient();
client.setPeg(square);
//客户端不用修改,同样是调用insert,实际上是调用方形桩的insertIntoHole
client.insert();

上面的代码是否可以这样理解:
SquareClient类的setPeg()方法中的参数只能是SquarePeg类及其子类。而我们要使client.insert()既能打方形桩也能打圆形桩:

//用圆形桩对象为参数,构造adapter
PegAdapter square = new PegAdapter(roundObject);
SquarePeg square2 = new SquarePeg();
SquareClient client = new SquareClient();
client.setPeg(square);
//打圆形桩;
client.insert();
client.setPeg(square2);
//打方形桩;
client.insert();

我开始一直把PegAdapter类理解成既能打方形桩也能打圆形桩的。
现在我明白了:PegAdapter类就像SquarePeg类娶进门的老婆,徒有名分而已,而实际上天天晚上和RoundPeg类睡在一起。
power1128

发表文章: 52
注册时间: 2006年05月24日 14:37
给他发消息
回复:re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月16日 17:22 回复
你最后那个比喻有意思:)

我也有个比喻:就好像cpu的转接卡一样,比如940针转939针,使的940针的cpu能在939针的主板上用,这个转接卡就像一个adpater.我也正在学设计模式,刚看到bridge,呵呵,大家一起学习
tellhow

发表文章: 13
注册时间: 2007年04月09日 13:48
给他发消息
re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月17日 09:46 回复
呵呵,我也看了下bridge,对有些地方不理解:

看看是如何动态结合的,在使用之前,我们做个准备工作,设计一个单态类
(Singleton)用来hold当前的CoffeeImp:

public class CoffeeImpSingleton
{
  private static CoffeeImp coffeeImp;

  public CoffeeImpSingleton(CoffeeImp coffeeImpIn)
   {this.coffeeImp = coffeeImpIn;}

  public static CoffeeImp getTheCoffeeImp()
  {
    return coffeeImp;
  }
}


倒咖啡这个案例,为什么要设计一个单态类(Singleton)来hold当前的CoffeeImp呢? 如果不设计单态类(Singleton),为出现什么问题?设计了单态类(Singleton)后,如果以后我们加了牛奶还要加糖怎么办?
Coolyu0916

发表文章: 196
注册时间: 2007年04月23日 11:29
给他发消息
re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月17日 09:58 回复
无所谓的事情,估计是为了说明的简单
不过一般我觉得是使用factory模式的

public abstract class Coffee
{
  CoffeeImp coffeeImp;

  public void setCoffeeImp() {
    this.CoffeeImp = CoffeeImpSingleton.getTheCoffeImp();
//this.CoffeeImp = CoffeeImpFactory.create()//这样是开发中常用的形式。
  }

  public CoffeeImp getCoffeeImp() {return this.CoffeeImp;}

  public abstract void pourCoffee();
}
power1128

发表文章: 52
注册时间: 2006年05月24日 14:37
给他发消息
回复:re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月17日 19:08 回复
如果又要加奶又要加糖,可能要新加一个行为接口的实现,比如叫MilkSugarCoffeeImp,在这个类的pourCoffeeImp()方法里实现既加糖又加奶的操作,然后行为工厂创建该类的一个对象,传递给Coffee
tellhow

发表文章: 13
注册时间: 2007年04月09日 13:48
给他发消息
re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月18日 09:29 回复
我们之所以学习设计模式,是为了提高程序的可重用性和可拓展性,延长软件的生命!
bridge模式的倒咖啡案例中有四种咖啡:
1.中杯加奶
2.中杯不加奶
3.大杯加奶
4.大杯不加奶
为什么要设计一个单态类(Singleton)来hold当前的CoffeeImp呢?

如果让CoffeeImp再多一种选择:糖,那么就有八种咖啡:
1.中杯只加奶
2.中杯只加糖
3.中杯奶和糖都加
4.中杯奶和糖都不加
5.大杯只加奶
6.大杯只加糖
7.大杯奶和糖都加
8.大杯奶和糖都不加
以后CoffeeImp可能还有更多的选择.
bridge模式再加什么模式能实现这些功能的拓展呢?
tellhow

发表文章: 13
注册时间: 2007年04月09日 13:48
给他发消息
re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月18日 09:38 回复
banq大虾工作比较忙,而且他的回复太深奥,我们这些初学者挺难深刻理解的!
我觉得应该对每个设计模式都开个帖,初学者都进来讨论讨论,谈谈自己的见解,共同学习,共同进步!
Coolyu0916

发表文章: 196
注册时间: 2007年04月23日 11:29
给他发消息
re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月18日 09:57 回复
banq只是一个举例,那你不需要那么认真。

现在我的问题是你在咖啡里面加奶、加糖,你甚至可以加胡椒,加番茄酱,加任何东西,但是你加了这些东西之后希望做什么那??只是为了得到一杯咖啡么??我想应该是为了咖啡的味道变化吧。你可以设置每个都有一个改变味道的方法,那么当咖啡使用的时候,我们可以让咖啡变舔,当你的匹萨饼使用的时候匹萨的味道依然是变甜。这样才能道道你的软件复用。

那么我们再近一步,可能糖可以使东西变甜,牛奶也可以,蜂蜜也可以,用户可以任意选择怎么办??那么就是定义一个接口具备变甜的方法,然后糖实现它,牛奶、蜂蜜都实现它。这样做就更加灵活了。
tellhow

发表文章: 13
注册时间: 2007年04月09日 13:48
给他发消息
re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月19日 15:49 回复
bridge模式的定义:将抽象和行为划分开来,各自独立,但能动态的结合.

在咖啡案例中,
中杯和大杯是抽象的.
加牛奶和不加牛奶是行为.
通过bridge模式将这两个概念分开并动态的结合起来.

问题就出在:行为是多样的,我们加了牛奶后还可以加其他的比如糖,蜂蜜.

感谢power1128 兄台的回复!
在power1128 的回复中有提到:如果又要加奶又要加糖,可能要新加一个行为接口的实现,比如叫MilkSugarCoffeeImp,在这个类的pourCoffeeImp()方法里实现既加糖又加奶的操作,然后行为工厂创建该类的一个对象,传递给Coffee

power1128是把又要加奶又要加糖看成一种行为了.这样一来系统的复杂性必然随着行为种类的增多而增加.

感谢Coolyu0916 兄台的回复!
Coolyu0916是将改变味道作为一种行为,而将加糖,牛奶、蜂蜜做为甜味道的具体实现.如果要又加牛奶又加辣椒,这种味道就不太好说了!

我个人的想法是:采用bridge模式+Decorator(油漆工)模式.
Decorator(油漆工)模式能够动态地实现各种行为.
比如我要又加糖又加牛奶:
MediumCoffee mediumCoffee=new MediumCoffee();
Decorator decorator=new Decorator();
decorator.add("加糖");
decorator.add("加牛奶");
mediumCoffee.pourCoffee(decorator.get());

不知道这样做可不可以?
[该贴被tellhow于2007年04月19日 16:05修改过]
[该贴被tellhow于2007年04月19日 16:05修改过]
Coolyu0916

发表文章: 196
注册时间: 2007年04月23日 11:29
给他发消息
re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月19日 17:12 回复
楼上的好像这不是Decorator模式
通常Decorator具备跟原来的接口一样的方法,
只是在做接口方法的前面可以做一些其他的事情。
tellhow

发表文章: 13
注册时间: 2007年04月09日 13:48
给他发消息
re:求教设计模式之Adapter(适配器)的问题 发表: 2007年04月20日 09:22 回复
>楼上的好像这不是Decorator模式
通常Decorator具备跟原来的接口一样的方法,
只是在做接口方法的前面可以做一些其他的事情。

上面的代码我随便写的,只是表示下意思,并没跟着banq的代码来.上面的Decorator类当然是CoffeeImp行为接口的子类了,也当然具备原来的接口一样的方法,Decorator类还具备父类没有的add方法,remove方法,clear方法和get方法.add方法的参数类型也是CoffeeImp,参数植是行为的具体实例,比如milkCoffeeImp等等!
我上面代码:
decorator.add("加糖");
decorator.add("加牛奶");
参数类型是String类型,只是表示下意思,实际上参数类型应该是CoffeeImp.

get方法返回List.

需要注意的是:不应该把"什么也没加"看成一种行为,而应该看成一种状态.只有两种状态:"加了东西"(糖,牛奶等等!)和"什么都没有加"!
pourCoffee方法应该加上一个判断:
if(impList.size==0){
System.out.println("什么也没加,清香!");
}

上面都是我的愚见,不足之处请大虾们提出!
关于Decorator(油漆工)的介绍在下面的网页上有http://www.jdon.com/designpatterns/decorator.htm
这个主题有 24 回复 / 2 页 [ 1 2 下一页 ]
???en_US.forumThreadPrev.name??? 上一主题
Go back to the topic listing   返回主题列表    返回页首  返回页首
???en_US.forumThreadNext.name??? 下一主题
热点TAG: AOP cache DDD EJB 集群 设计模式 Hibernate IOC JiveJdon OO RBAC Spring Struts
查询本论坛内 回复超过的热门帖子
快速发表回复
标题
 
粗体 斜体 下划线 插入图片 插入代码 插入url链接 插入附件
内容
 

解惑之道在J道 ,打造中国最具影响力的的企业软件社区
OpenSource JIVEJDON v3.0 Powered by JdonFramework Code © 2002-08 jdon.com

anti spam