设计模式
设计模式简介
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。(设计模式是前人解决一些开发问题中总结的经验书面化的结果,是从实践中总结出的经验,就像三十六计一样,大家要活学活用)
设计模式值适配器模式
适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。
举个例子:
我有一台itel手机,使用的是220v的电压充电,但是世界上又不止只有220v这一个电压,比如美国的标准电压是110v.
那我们定义一个itel手机的类ItelPhone
public class ItelPhone{
private Adapter mAdapter;
public ItelPhone(){}
public ItelPhone(Adapter adapter){
this.mAdapter = adapter;
}
public void Charing(){
if(mAdapter!=null){
System.out.println("适配器220v充电");
}else{
System.out.println("正常220v充电");
}
}
}
然后我们哪两种电压来举个例子110v和220v
220v的电压
public interface ChinaVoltage{
void is220v{};
}
public interface USAVoltage{
void is110v{};
}
首先我们的适配器有两个连接口一个是连接110v插座的一个是连接手机的,下面是连接110v插座的实现
private ChinaVoltage mChinaVoltage;
public UTCAdapter (ChinaVoltage mChinaVoltage){
this.mChinaVoltage=mChinaVoltage;
}
public void is110v(){
mChinaVoltage.is220v();
}
}
再下面一步是将手机插到适配器上面充电
public class Clienter {
public static void main(String[] args) {
实例化一个220v电压mChinaVoltage(此处省略代码);
UTCAdapter mUTCAdapter = new UTCAdapter(mChinaVoltage);
ItelPhone mItelPhone = new ItelPhone(mUTCAdapter);
mItelPhone.Charing();
}
这样就通过一个适配器合理的完成了itel手机的充电。
下面是网上看的一篇文档他将适配器细分了一下,解单讲解一下。
适配器模式有两种:类适配器、对象适配器、接口适配器
前二者在实现上有些许区别,作用一样,第三个接口适配器差别较大。
1、类适配器模式:
原理:通过继承来实现适配器功能。
当我们要访问的接口A中没有我们想要的方法,却在另一个接口B中发现了合适的方法,我们又不能改变访问接口A,在这种情况下,我们可以定义一个适配器p来进行中转,这个适配器p要实现我们访问的接口A,这样我们就能继续访问当前接口A中的方法(虽然它目前不是我们的菜),然后再继承接口B的实现类BB,这样我们可以在适配器P中访问接口B的方法了,这时我们在适配器P中的接口A方法中直接引用BB中的合适方法,这样就完成了一个简单的类适配器。
详见下方实例:我们以ps2与usb的转接为例
ps2接口:Ps2
1public interface Ps2 {
2 void isPs2();
3 }
USB接口:Usb
1public interface Usb {
2 void isUsb();
3 }
USB接口实现类:Usber
1public class Usber implements Usb {
2
3 @Override
4 public void isUsb() {
5 System.out.println("USB口");
6 }
7
8 }
适配器:Adapter
1public class Adapter extends Usber implements Ps2 {
2
3 @Override
4 public void isPs2() {
5 isUsb();
6 }
7
8 }
测试方法:Clienter
1public class Clienter {
2
3 public static void main(String[] args) {
4 Ps2 p = new Adapter();
5 p.isPs2();
6 }
7
8 }
显示结果:
USB口
实例讲解:
我手中有个ps2插头的设备,但是主机上只有usb插头的插口,怎么办呢?弄个转换器,将ps2插头转换成为USB插头就可以使用了。
接口Ps2:描述ps2接口格式
接口Usb:描述USB接口格式
类Usber:是接口Usb的实现类,是具体的USB接口格式
Adapter:用于将ps2接口格式转换成为USB接口格式
2、对象适配器模式
原理:通过组合来实现适配器功能。
当我们要访问的接口A中没有我们想要的方法,却在另一个接口B中发现了合适的方法,我们又不能改变访问接口A,在这种情况下,我们可以定义一个适配器p来进行中转,这个适配器p要实现我们访问的接口A,这样我们就能继续访问当前接口A中的方法(虽然它目前不是我们的菜),然后在适配器P中定义私有变量C(对象)(B接口指向变量名),再定义一个带参数的构造器用来为对象C赋值,再在A接口的方法实现中使用对象C调用其来源于B接口的方法。
详见下方实例:我们仍然以ps2与usb的转接为例
ps2接口:Ps2
1public interface Ps2 {
2 void isPs2();
3 }
USB接口:Usb
1publicinterface Usb {
2 void isUsb();
3 }
USB接口实现类:Usber
1public class Usber implements Usb {
2
3 @Override
4 public void isUsb() {
5 System.out.println("USB口");
6 }
7
8 }
适配器:Adapter
1publicclass Adapter implements Ps2 {
2
3 private Usbusb;
4 public Adapter(Usb usb){
5 this.usb =usb;
6 }
7 @Override
8 public void isPs2() {
9 usb.isUsb();
10 }
11
12 }
测试类:Clienter
1public class Clienter {
2
3 public static void main(String[] args) {
4 Ps2 p = new Adapter(new Usber());
5 p.isPs2();
6 }
7
8 }
结果显示:
USB口
实例讲解:
我手中有个ps2插头的设备,但是主机上只有usb插头的插口,怎么办呢?弄个转换器,将ps2插头转换成为USB插头就可以使用了。
接口Ps2:描述ps2接口格式
接口Usb:描述USB接口格式
类Usber:是接口Usb的实现类,是具体的USB接口格式
Adapter:用于将ps2接口格式转换成为USB接口格式
(备注:类适配器是通过继承实现的,对象适配器是通过组合实现的,能用对象适配器模式的时候就用对象适配器,多用组合少用继承,适配器模式总结下来我觉得就两个字那就是“组合”)
3、接口适配器模式
原理:通过抽象类来实现适配,这种适配稍别于上面所述的适配。
当存在这样一个接口,其中定义了N多的方法,而我们现在却只想使用其中的一个到几个方法,如果我们直接实现接口,那么我们要对所有的方法进行实现,哪怕我们仅仅是对不需要的方法进行置空(只写一对大括号,不做具体方法实现)也会导致这个类变得臃肿,调用也不方便,这时我们可以使用一个抽象类作为中间件,即适配器,用这个抽象类实现接口,而在抽象类中所有的方法都进行置空,那么我们在创建抽象类的继承类,而且重写我们需要使用的那几个方法即可。
目标接口:A
1public interface A {
2 void a();
3 void b();
4 void c();
5 void d();
6 void e();
7 void f();
8 }
适配器:Adapter
1public abstract class Adapter implements A {
2 publicvoid a(){}
3 publicvoid b(){}
4 publicvoid c(){}
5 publicvoid d(){}
6 publicvoid e(){}
7 publicvoid f(){}
8 }
实现类:Ashili
1public class Ashili extends Adapter {
2 publicvoid a(){
3 System.out.println("实现A方法被调用");
4 }
5 publicvoid d(){
6 System.out.println("实现d方法被调用");
7 }
8 }
测试类:Clienter
1public class Clienter {
2
3 publicstaticvoid main(String[] args) {
4 A a = new Ashili();
5 a.a();
6 a.d();
7 }
8
9 }
4、适配器模式应用场景
类适配器与对象适配器的使用场景一致,仅仅是实现手段稍有区别,二者主要用于如下场景:
(1)想要使用一个已经存在的类,但是它却不符合现有的接口规范,导致无法直接去访问,这时创建一个适配器就能间接去访问这个类中的方法。
(2)我们有一个类,想将其设计为可重用的类(可被多处访问),我们可以创建适配器来将这个类来适配其他没有提供合适接口的类。
以上两个场景其实就是从两个角度来描述一类问题,那就是要访问的方法不在合适的接口里,一个从接口出发(被访问),一个从访问出发(主动访问)。
接口适配器使用场景:
(1)想要使用接口中的某个或某些方法,但是接口中有太多方法,我们要使用时必须实现接口并实现其中的所有方法,可以使用抽象类来实现接口,并不对方法进行实现(仅置空),然后我们再继承这个抽象类来通过重写想用的方法的方式来实现。这个抽象类就是适配器。