Java设计模式(一)
副标题#e#
什么是设计模式?
假如一个问题一再地呈现,就必需找到一个可以或许有效办理问题的要领。谁人要领就被描写成模式。设计模式是独立于编程语言的,用来办理常见的,面向工具的设计问题的计策。当你实施设计的时候,你应该知晓一些常见的办理之道的名称。通晓设计模式可以使人们彼此间做有效的交换。实际上,你大概已经对一些设计模式很熟悉了,你只是没有用各人耳熟能详的称呼来描写它们罢了。太阳公司发起利用GOF(“四人帮”,指写了“设计模式-可反复利用的面向工具软件的元素”一书的四位先驱),所以我们应用那本书作为指导来描写办理之道。你也需要让本身对这些术语熟悉起来,看看别人是如何用它们来办理编程问题的。
必然要利用设计模式吗?
假如你但愿成为一位Java的职业措施员,你至少该当晓得一些很风行的办理编码问题的要领。这些要领已被有履历的措施员在实践中证明很是有效。它们就是所谓的设计模式。进修设计模式可以加快你在OOA/OOD规模的履历积聚。一旦你把握了它们,你将会终生收益,并让本身成为设计和开拓规模的大家。并且,你也可以利用这些术语和你的同行们更高效地交换。
很多有多年履历的措施员并不知道设计模式,可是作为一个OO的措施员,你必需熟知它们,出格是对那些新学Java的人。实际上,当你办理一个编程问题时,你就已经在利用设计模式了。你只是没有用一些风行的术语来称号它们罢了,可能没有选择一个有效处所法从常识产权的角度来更好地节制你的成就。进修有履历的开拓人员是如何来办理编程问题的,并应用到你本身的项目上去是赢得履历和证明的最好要领。
记着,进修设计模式必然会改变你编程的要领;你不可是会变得睿智,你会变得很是的睿智。
有几多设计模式?
很多。一个网站上说在OO的规模中,至少有250种模式,包罗“意大利面条”式(指低效糟糕的代码)。被GOF应用的23种设计模式广为人知,很多模式还在摸索和发明中。
对了,提醒一句,设计模式不是术语,算法,或组件。
设计模式间的彼此干系
一般来讲,制作一个系统,需要将很多设计模式编排在一起。差异的设计师大概利用差异的模式来办理同一个问题。凡是来说:
一些模式间相处调和
一个模式可以激发出另一个模式
一些模式很雷同,可以彼此替代
模式是可以被发明并文档化的
模式不是要领或架构
模式可以给出一些有效办理问题的提示
建设性模式
抽象工场(Abstract Factory)界说
提供比工场模式(Factory Pattern)高一级的接口。一般被用来返回多个工场中的某一个工场。
何时利用以及长处
建设了相互关联和依靠的家属型工具,好比Kit
提供了产物的类库,对外展示接口,而不是实施细节
将详细的类和它们的父类隔分开来
一个系统需要独立于它的产物的建设,构成,和表达
需要强制实施一个限制
在外貌之外的另一个选择,可用来埋没与平台有关的类
可以很容易的对一个系统和家属实施担任
与此相关的设计模式包罗,
工场要领(Factory Method),凡是用抽象工场的要领来实施
单例(Singleton),凡是用抽象工场的要领来实施
原型(Prototype),凡是用抽象工场的要领来实施
外观(Facade),凡是与抽象工场一同利用,来提供一个可以建设实施类的接口
#p#副标题#e#
代码举例
假设你需要一个措施在差异的处所来显示数据,好比从当地和长途的数据库。在与数据打交道之前,你需要成立一个和数据库的毗连。在这个case里,你有两个选择,当地数据库和长途数据库。你可以利用一个抽象工场的模式来设计这个接口:
class DataInfo {}
interface Local {
DataInfo[] loadDB(String filename);
}
interface Remote extends Local{
void connect2WWW(String url);
}
class LocalMode implements Local {
public DataInfo[] loadDB(String name) {
System.out.print("Load from a local database ");
return null;
}
}
class RemoteMode implements Remote {
public void connect2WWW(String url) {
System.out.println("Connect to a remote site ");
}
//下面是对loadDB要领的另一种实施 public DataInfo[] loadDB(String name) {
System.out.println("Load from a remote database ");
return null;
}
}
#p#分页标题#e#
//下面就是抽象工场了interface ConnectionFactory {
Local getLocalConnection();
Remote getRemoteConnection();
}
class DataManager implements ConnectionFactory {
boolean local = false;
DataInfo[] data;
//...
public Local getLocalConnection() {
return new LocalMode();
}
public Remote getRemoteConnection() {
return new RemoteMode();
}
public void loadData() {
if(local){
Local conn = getLocalConnection();
data = conn.loadDB("db.db");
}else {
Remote conn = getRemoteConnection();
conn.connect2WWW("www.some.where.com");
data = conn.loadDB("db.db");
}
}
// work on data
public void setConnection(boolean b) {
local = b;
}
}
//用以下测试要领来测试上述的类class Test {
public static void main(String[] args) {
DataManager dm = new DataManager();
DataInfo[] di = null;
String dbFileName = "db.db"$$
if (args.length == 1) {
//assume local is set to true
dm.setConnection(true);
LocalMode lm = (LocalMode)dm.getLocalConnection();
di = lm.loadDB(dbFileName);
} else {
//Note: dm.local = false is default setting
RemoteMode rm = (RemoteMode)dm.getRemoteConnection();
rm.connect2WWW("www.javacamp.org/db/");
di = rm.loadDB(dbFileName);
}
//以下就可以仅仅利用一套要领来处理惩罚用上述要领加载的数据
//Like di.find(), di.search() etc.
//以后,不需再为数据库的毗连而担忧
}
}
下面是从呼吁行挪用Test类而举办测试的环境,留意,因参数的差异,而呈现的差异运行功效。
C:> java Test
Connect to a remote site
Load from a remote database
C:> java Test local
Load from a local database
C: Comma
这样的设计一般会用在在Sun公司开拓人员的认证测验中。假如你可以从差异的处所加载数据,你只需在connection工场接口中插手一个要领,在符合的位置实施它,而不需对其他措施布局有丝毫的改变。