设计模式java.docx
- 文档编号:30667490
- 上传时间:2023-08-19
- 格式:DOCX
- 页数:35
- 大小:61.23KB
设计模式java.docx
《设计模式java.docx》由会员分享,可在线阅读,更多相关《设计模式java.docx(35页珍藏版)》请在冰豆网上搜索。
设计模式java
JAVA的设计模式
一、设计模式的六大原则:
1、单一职责原则
不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,如若不然,就应该把类拆分。
2、里氏替换原则(LiskovSubstitutionPrinciple)
里氏代换原则(LiskovSubstitutionPrincipleLSP)面向对象设计的基本原则之一。
里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。
LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
里氏代换原则是对“开-闭”原则的补充。
实现“开-闭”原则的关键步骤就是抽象化。
而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
历史替换原则中,子类对父类的方法尽量不要重写和重载。
因为父类代表了定义好的结构,通过这个规范的接口与外界交互,子类不应该随便破坏它。
3、依赖倒转原则(DependenceInversionPrinciple)
这个是开闭原则的基础,具体内容:
面向接口编程,依赖于抽象而不依赖于具体。
写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。
4、接口隔离原则(InterfaceSegregationPrinciple)
这个原则的意思是:
每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。
使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。
5、迪米特法则(最少知道原则)
就是说:
一个类对自己依赖的类知道的越少越好。
也就是说无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。
这样当被依赖的类变化时,才能最小的影响该类。
最少知道原则的另一个表达方式是:
只与直接的朋友通信。
类之间只要有耦合关系,就叫朋友关系。
耦合分为依赖、关联、聚合、组合等。
我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。
局部变量、临时变量则不是直接的朋友。
我们要求陌生的类不要作为局部变量出现在类中。
6、合成复用原则
原则是尽量首先使用合成/聚合的方式,而不是使用继承。
二、常见模式介绍
1.创建模式
工厂方法模式
适用场景:
首先,作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。
有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式。
如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
其次,工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。
假如调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂模式。
将会大大降低对象之间的耦合度。
再次,由于工厂模式是依靠抽象架构的,它把实例化产品的任务交由实现类完成,扩展性比较好。
也就是说,当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装。
流程:
先定义一个创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
代码示例:
interfaceIProduct{
publicvoidproductMethod();
}
classProductimplementsIProduct{
publicvoidproductMethod(){
System.out.println("产品");
}
}
interfaceIFactory{
publicIProductcreateProduct();
}
classFactoryimplementsIFactory{
publicIProductcreateProduct(){
returnnewProduct();
}
}
publicclassClient{
publicstaticvoidmain(String[]args){
IFactoryfactory=newFactory();
IProductprodect=factory.createProduct();
prodect.productMethod();
}
}
由上我们可以看出:
我们本质的目的创建一个类(Product),但是这个类是复杂可变的,通过工厂模式,将产品的实例化封装起来,使得调用者根本无需关心产品的实例化过程,只需依赖工厂即可得到自己想要的产品,所以我们用一个工厂的方法createProduct()来实例化这个类(Product),创建这个类(Product)。
抽象工厂模式
适用场景:
我们的工厂类一次只可以处理一类产品。
那么如果我们想处理多类产品,简单工厂是满足不了的。
必须要用抽象工厂设计模式。
尤其涉及多人各自创建自己的类的时候而且相互的类之间有关联。
流程:
1、用抽象工厂生产抽象产品
2、用实体工厂生产实体产品
3、用抽象产品提供实体产品访问接口
4、用实体产品实现自己的功能
代码示例:
定义抽象产品:
///抽象产品A
publicabstractclassCar
{
publicabstractvoidRun();
}
抽象产品B
publicinterfaceIBus
{
voidRun();
}
定义实体产品
publicclassBMWCar:
Car
{
publicoverridevoidRun()
{
Console.WriteLine("宝马轿车在行驶!
");
}
}
publicclassBenzCar:
Car
{
publicoverridevoidRun()
{
Console.WriteLine("奔驰轿车在行驶!
");
}
}
定义抽象工厂
publicabstractclassAbstractFactory
{
publicstaticAbstractFactoryCreateFactory(stringstrType)
{
AbstractFactoryfactory=null;
switch(strType)
{
case"BMW":
factory=newBMWFactory();
break;
case"Benz":
factory=newBenzFactory();
break;
}
returnfactory;
}
publicabstractCarCreateCar();
publicabstractIBusCreateBus();
}
定义实体工厂
publicclassBMWFactory:
AbstractFactory
{
publicoverrideCarCreateCar()
{
returnnewBMWCar();
}
publicoverrideIBusCreateBus()
{
returnnewBMWBus();
}
}
最后调用
staticvoidMain(string[]args)
{
AbstractFactoryfactory=AbstractFactory.CreateFactory("Benz");
Carcar=factory.CreateCar();
car.Run();
IBusbus=factory.CreateBus();
bus.Run();
}
由此看出:
这因为我们的用户只关心抽象工厂与抽象方法,即只需要自己所需的服务,这种模式不关心具体的实现方法,这种模式让我们只关心做好接口,调用接口的方法,来创建自己所需的类,来获得实体接口所提供的服务
建造者模式
适用场景:
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
[构建与表示分离,同构建不同表示]
流程:
某一个类比较多,有许多的熟悉以及组件,这个时候需要一个构建者来
代码示例:
publicinterfaceBuilder{
voidbuildPartA();
voidbuildPartB();
voidbuildPartC();
ProductgetResult();
}
//具体建造工具
publicclassConcreteBuilderimplementsBuilder{
PartpartA,partB,partC;
publicvoidbuildPartA(){
//这里是具体如何构建partA的代码
};
publicvoidbuildPartB(){
//这里是具体如何构建partB的代码
};
publicvoidbuildPartC(){
//这里是具体如何构建partB的代码
};
publicProductgetResult(){
//返回最后组装成品结果
};
}
//建造者
publicclassDirector{
privateBuilderbuilder;
publicDirector(Builderbuilder){
this.builder=builder;
}
publicvoidconstruct(){
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
}
}
publicinterfaceProduct{}
publicinterfacePart{}
下面是调用builder的方法:
ConcreteBuilderbuilder=newConcreteBuilder();
Directordirector=newDirector(builder);
director.construct();
Productproduct=builder.getResult();
由此看出:
建造者模式主要是使复杂对象的创建过程变得短小简单。
单态模式
适用场景:
保证在JAVA应用程序中某些特定的类只有一个实例存在,节省内存及系统开销。
只在第一次使用时进行创建。
并且它由于限制了实例个数,有利于垃圾回收。
流程:
创建一个公共的单例的实体化方法。
代码示例:
publicclassSingleton{
privateSingleton(){
//通过添加一个私有构造函数以避免外部程序自行实例化该对象
}
privatefinalSingletoninstance=newSingleton();
publicSingletongetInstance(){
returninstance;
}
publicvoidhello(){
System.out.println("hellosinory");
}
}
由此看出:
单态模式十分简单,但是经常被使用,尤其是一些特定的业务或者数据库连接池之类的场合
原型模式
适用场景:
原型模式要求对象实现一个可以“克隆”自身的接口,这样就可以通过复制一个实例对象本身来创建一个新的实例。
这样一来,通过原型实例创建新的对象,就不再需要关心这个实例本身的类型,只要实现了克隆自身的方法,就可以通过这个方法来获取新的对象,而无须再去通过new来创建。
流程:
在抽象原型端申明一个克隆自身的接口,在具体原型实现克隆自身的操作,在客户端让一个原型复制自身从而创建一个新的对象。
代码示例:
抽象原型角色
publicinterfacePrototype{
/**
*克隆自身的方法
*@return一个从自身克隆出来的对象
*/
publicObjectclone();
}
具体原型角色
publicclassConcretePrototype1implementsPrototype{
publicPrototypeclone(){
//最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
Prototypeprototype=newConcretePrototype1();
returnprototype;
}
}
publicclassConcretePrototype2implementsPrototype{
publicPrototypeclone(){
//最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
Prototypeprototype=newConcretePrototype2();
returnprototype;
}
}
客户端角色
publicclassClient{
/**
*持有需要使用的原型接口对象
*/
privatePrototypeprototype;
/**
*构造方法,传入需要使用的原型接口对象
*/
publicClient(Prototypeprototype){
this.prototype=prototype;
}
publicvoidoperation(Prototypeexample){
//需要创建原型接口的对象
PrototypecopyPrototype=prototype.clone();
}
}
由此看出:
原型模式主要是创建跟现存的对象类型一致的对象
2.结构模式
适配器模式
适用场景:
1.你想使用一个已经存在的类,而它的接口不符合你的需求。
2.你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那未知的接口可能不一定兼容的类)协同工作。
3.(仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。
对象适配器可以适配它的父类接口。
流程:
比较现有类与用户需求的类与现有类的差距,然后创建一个用户需求的target借口,再创建一个适配器类,它继承现有现有类的方法,实现不存在的那些方法,从而来让用户通过适配器使用了现有类的方法。
代码示例:
Target
publicinterfaceTarget{
voidadapteeMethod();
voidadapterMethod();
}
Adaptee
publicclassAdaptee{
publicvoidadapteeMethod(){
System.out.println("Adapteemethod!
");
}
}
Adapter
publicclassAdapterimplement*Target{
privateAdapteeadaptee;
publicAdapter(Adapteeadaptee){
this.adapter=adaptee;
}
publicvoidadapteeMethod(){
adaptee.adapteeMethod();
}
publicvoidadapterMethod(){
system.out.println("Adaptermethod!
");
}
}
Client
publicclassTest{
publicstaticvoidmain(String[]args){
Targettarget=newAdapter(newAdaptee());
target.adapteeMethod();
target.adapterMethod();
}
}
result
Adapteemethod!
Adaptermethod!
由此看出:
适配器模式主要是抹平目标类与现实类之间的差距,通过建造一个适配器,实现target接口继承现实类从而创建满足用户需求的类
桥接模式
适用场景:
将某个问题抽象的不同形式分别与该问题的具体实现部分相分离,使他们都可以独立变化,并能够动态结合。
流程:
先创建不同组件类使其可变,然后通过相互的组装配合,生产出不同的对象
代码示例:
创建电视机
publicabstractclassTelevision{
//电视厂商
protectedTelevisionMakertelevisionMaker;
//收看电视
abstractpublicvoidteleview(TelevisionMakertelevisionMaker);
}
创建生产厂商
publicabstractclassTelevisionMaker{
abstractpublicvoidproduce();
}
电视机的型号,即继承电视机类
publicclassInch21extendsTelevision{
publicvoidteleview(TelevisionMakertelevisionMaker){
System.out.println("21寸电视");
}
}
publicclassInch29extendsTelevision{
publicvoidteleview(TelevisionMakertelevisionMaker){
System.out.println("29寸电视");
}
}
下面是不同厂商,即继承生产厂商
publicclassChangHongextendsTelevisionMaker{
publicChangHong(){
System.out.println("长虹厂商");
}
publicvoidproduce(){
System.out.println("长虹厂商");
}
}
publicclassHaierextendsTelevisionMaker{
publicHaier(){
System.out.println("海尔厂商");
}
publicvoidproduce(){
System.out.println("海尔厂商");
}
}
我们也可以根据用户的需要,得到他所需要的电视机,如长虹厂商出厂的29寸电视机
publicclassClient{
publicstaticvoidmain(String[]args){
Inch29i=newInch29();
i.teleview(newChangHong());
}
}
由此看出:
桥接模式主要是根据动态需求,使组件间动态的进行结合
组合模式
适用场景:
忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
流程:
先创建不同组件类使其可变,然后通过相互的组装配合,生产出不同的对象
代码示例:
interfaceNode{
publicvoidcopy();//定义统一的接口:
复制
}
classFolderimplementsNode{
privateStringfolderName;
privateArrayListnodeList=newArrayList();
publicFolder(StringfolderName){
this.folderName=folderName;
}
publicvoidadd(Nodenode){//增加文件或文件夹
nodeList.add(node);
}
publicvoidcopy(){//文件夹复制操作实现递归
System.out.println("复制文件夹:
"+folderName);
for(inti=0;i Nodenode=(Node)nodeList.get(i); node.copy(); } } } classFileimplementsNode{ privateStringfileName; publicFile(StringfileName){ this.fileName=fileName; } publicvoidcopy(){ System.out.println("复制文件: "+fileName); } } 由此看出: 通过实现组合模式,我们对组合对象的操作与对单一对象的操作具有一致性。 调用者不用关心这是组合对象还是文件,也不用关心组合对象内部的具体结构,就可以调用相关方法,实现功能 这里由于时间的原因,以下的我只能完全使用网上的资料了 装饰模式 装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性。 动态给一个对象增加功能,这些功能可以再动态的撤消。 增加由一些基本功能的排列组合而产生的非常大量的功能。 Mary过完轮到Sarly过生日,还是不要叫她自己挑了,不然这个月伙食费肯定玩完,拿出我去年在华山顶上照的照片,在背面写上“最好的的礼物,就是爱你的Fita”,再到街上礼品店买了个像框(卖礼品的MM也很漂亮哦),再找隔壁搞美术设计的Mike设计了一个漂亮的盒子装起来……,我们都是Decorator,最终都在修饰我这个人呀,怎么样,看懂了吗? publicinterfaceWork { publicvoidinsert(); } publicclassSquarePegimplementsWork{ publicvoidinsert(){ System.out.println("方形桩插入"); } } publicclassDecoratorimplementsWork{ privateWorkwork; //额外增加的功能被打包在这个List中 privateArrayListothers=newArrayList(); //在构造器中使用组合new方式,引入Work对象; publicDecorator(Workwork) { this.work=work; others.add("挖坑");
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 设计 模式 java