网站建设 该如何选好域名,惠州网站建设是什么意思,wordpress api 自定义认证,股票软件定制#1024程序员节#xff5c;征文#
4.1 适配器模式
结构型模式#xff08;Structural Pattern#xff09;的主要目的就是将不同的类和对象组合在一起#xff0c;形成更大或者更复杂的结构体。结构性模式的分类#xff1a;
类结构型模式关心类的组合#xff0c;由多个类…#1024程序员节征文#
4.1 适配器模式
结构型模式Structural Pattern的主要目的就是将不同的类和对象组合在一起形成更大或者更复杂的结构体。结构性模式的分类
类结构型模式关心类的组合由多个类可以组合成一个更大的系统在类结构型模式中一般只存在继承关系和实现关。
对象结构型模式关心类与对象的组合通过关联关系在一个类中定义另一个类的实例对象然后通过该对象调用相应的方法。根据合成复用原则在系统中尽量使用关联关系替代继承关系因此大部分结构型模式都是对象结构型模式。
4.1.1 适配器模式的定义
1.动机适配器可以使由于接口不兼容而不能交互的类可以一起工作这就是适配器模式的模式动机。
2.定义将一个接口转换成客户希望的另一个接口适配器模式使接口不兼容的那些类可以一起工作其别名为包装器
4.1.2 适配器模式的分析与实现
在适配器模式中可以定义一个包装类包装不兼容接口的对象这个包装类指的就是适配器Adaptor它所包装的对象就是适配者Adaptee即被适配的类。适配器提供客户类需要的接口适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。也就是说当客户类调用适配器的方法时在适配器类的内部将调用适配者类的方法而这个过程对客户类是透明的客户类并不直接访问适配者类。
类适配器 public interface Target {public void request();
}
public class Adaptee {public void specialRequest() {System.out.println(特殊的请求方式);}
}
public class Adapter extends Adaptee implements Target{Overridepublic void request() {super.specialRequest();}
}对象适配器 public interface Target {public void request();
}
public class Adaptee {public void specialRequest() {System.out.println(特殊的请求方式);}
}
public class Adapter implements Target {private Adaptee adaptee;public void setAdaptee(Adaptee adaptee) {this.adaptee adaptee;}Overridepublic void request() {adaptee.specialRequest();}
}类适配器模式违背了合成复用原则。类适配器是客户类有一个接口规范的情况下可用反之不可用。 适配者类无法继承时只能用对象适配器。
4.1.3 适配器模式的案例
现需要设计一个可以模拟各种动物行为的机器人在机器人中定义了一系列方法如机器人叫喊方法cry()、机器人移动方法move()等。如果希望在不修改已有代码的基础上使得机器人能够像狗一样叫像狗一样跑使用适配器模式进行系统设计。 public interface Robot {public void cry();public void move();
}
public class Dog {public void cry() {System.out.println(汪汪叫);}public void move() {System.out.println(快快跑);}
}
public class DogAdapter extends Dog implements Robot{public void cry(){super.cry();}public void move(){super.move();}
}4.1.4 适配器模式的优缺点
优点缺点1.将目标类和适配者类解耦通过引入一个适配器类来重用现有的适配者类无须修改原有结构2.增加了类的透明性和复用性提高了适配者的复用性3.灵活性和扩展性非常好更换(增加)适配器符合开闭原则4.类适配器模式由于继承关系置换一些适配者的方法很方便不能适配多个适配类每个目标类必须为接口对于适配类为finial修饰的不可使用5.对象适配器模式可以把多个不同的适配者适配到同一个目标还可以适配一个适配者的子类在适配器中置换适配者类的某些方法比较麻烦
4.1.5 适配器模式的适用场景 系统需要使用一些现有的类而这些类的接口不符合系统的需要甚至没有这些类的源代码 创建一个可以重复使用的类用于和一些彼此之间没有太大关联的类包括一些可能在将来引进的类一起工作
4.1.6 双向适配器类 public class Adapter implements Target,Adaptee {private Target target;private Adaptee adaptee;public Adapter(Target target) {this.target target; } public Adapter(Adaptee adaptee) {this.adaptee adaptee; } public void request() {adaptee.specificRequest(); } public void specificRequest() {target.request(); }
}4.2 桥接模式
4.2.1 桥接模式的定义
1.动机如果系统中某个类存在两个独立变化的维度通过该模式可以将这两个维度分离出来使得两者可以独立扩展。桥接模式用一种巧妙的方式处理多层继承存在的问题用抽象关联取代了传统的多重继承将类之间的静态继承关系转换为动态的对象组合关系使得系统更加灵活并易于扩展同时有效地控制了系统中类的个数。
2.定义将抽象部分与它的实现部分分离使它们都可以独立地变化。
4.2.2 桥接模式的分析与实现 桥接模式中体现开闭原则、合成复用原则、里氏代换原则、依赖倒转原则等。 脱耦桥接模式将抽象化和实现化之间的耦合解开或者说是将强关联继承改换成弱关联将两个角色之间的继承关系改为关联关系使得两者可以独立变化。 public interface Implementor {public void implOperation();
}
public class ConcreteImplementorA implements Implementor{Overridepublic void implOperation() {System.out.println(一个实体的维度1的特征A);}
}
public class ConcreteImplementorB implements Implementor{Overridepublic void implOperation() {System.out.println(一个实体的维度1的特征B);}
}public abstract class Abstracter {protected Implementor implementor;public void setImplementor(Implementor implementor) {this.implementor implementor;}public abstract void operation();
}
public class RefinedAbstracter extends Abstracter{Overridepublic void operation() {System.out.println(一个实体维度2的特征);implementor.implOperation();}
}4.2.3 桥接模式的案例 public interface VideoFile {public void decode(String osType, String fileName);
}
public class MPEGFile implements VideoFile{Overridepublic void decode(String osType, String fileName) {System.out.println(位于 osType 操作系统的 fileName .MPEG文件进行播放);}
}
public class WMVFile implements VideoFile{Overridepublic void decode(String osType, String fileName) {System.out.println(位于 osType 操作系统的 fileName .WMV文件进行播放);}
}public abstract class OSVersion {protected VideoFile videoFile;public void setVideoFile(VideoFile videoFile) {this.videoFile videoFile;}public abstract void play(String fileName);
}
public class LinuxVersion extends OSVersion{Overridepublic void play(String fileName) {videoFile.decode(Linux, fileName);}
}
public class WindowsVersion extends OSVersion{Overridepublic void play(String fileName) {videoFile.decode(Windows, fileName);}
}public class Main {public static void main(String[] args) {WMVFile wmvFile new WMVFile();WindowsVersion windowsVersion new WindowsVersion();windowsVersion.setVideoFile(wmvFile);windowsVersion.play(刺客五六七);MPEGFile mpegFile new MPEGFile();LinuxVersion linuxVersion new LinuxVersion();linuxVersion.setVideoFile(mpegFile);linuxVersion.play(喜羊羊与灰太狼);}
}4.2.4 桥接模式的优缺点
优点缺点1.分离抽象接口和实现部分1.不容易正确识别俩个变化的维度2.取代多继承减少子类个数2.关联关系在抽象层设计难度大3.扩展性俩个维度均可扩展
4.2.5 桥接模式的适用场景 需要在抽象化和具体化之间增加更多的灵活性扩展性避免在两个层次之间建立静态的继承关系 一个类存在两个或多个独立变化的维度且这两个或多个维度都需要独立地进行扩展 不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统
4.3 组合模式
4.3.1 组合模式的定义
1.动机描述了如何将容器对象和叶子对象进行递归组合使得用户在使用时无须对它们进行区分可以一致地对待容器对象和叶子对象。
2.定义组合多个对象形成树形结构以表示“部分-整体”的结构层次。组合模式对单个对象即叶子对象和组合对象即容器对象的使用具有一致性。
4.3.2 组合模式的分析与实现 组合模式用面向对象的方式来处理树形结构它为叶子构件和容器构件提供了一个公共的抽象构件类客户端可以针对该抽象类进行处理而无需关心所操作的是哪种类型的对象。使用聚合关系使得容器既可以添加叶子节点也可以添加容器
public abstract class Component {public abstract void add(Component component);public abstract void remove(Component component);public abstract Component getChild(int i);public abstract void method();
}public class Composite extends Component{private ArrayListComponent list new ArrayList();Overridepublic void add(Component component) {list.add(component);}Overridepublic void remove(Component component) {list.remove(component);}Overridepublic Component getChild(int i) {return list.get(i);}Overridepublic void method() {for (Component component : list) {component.method();}}
}public class Leaf extends Component{Overridepublic void add(Component component) {throw new RuntimeException(叶子节点无法添加元素);}Overridepublic void remove(Component component) {throw new RuntimeException(叶子节点无法删除元素);}Overridepublic Component getChild(int i) {throw new RuntimeException(叶子节点无法获取元素);}Overridepublic void method() {}
}4.3.3 组合模式的案例
在操作系统中一个文件夹中可能存放着图像文件视频文件文本文件也可能存放其他的文件夹而对不同类型的文件进行的浏览操作也不一样。 public abstract class AbstractFile {protected String fileName;public abstract void display();public abstract void add(AbstractFile file);public abstract void remove(AbstractFile file);
}public class ImageFile extends AbstractFile{public ImageFile(String fileName) {this.fileName fileName;}Overridepublic void display() {System.out.println(正在打开 this.fileName .png);}Overridepublic void add(AbstractFile file) {throw new RuntimeException(无法添加文件);}Overridepublic void remove(AbstractFile file) {throw new RuntimeException(无法删除文件);}
}
public class TextFile extends AbstractFile{public TextFile(String fileName) {this.fileName fileName;}Overridepublic void display() {System.out.println(正在打开 this.fileName .txt);}Overridepublic void add(AbstractFile file) {throw new RuntimeException(无法添加文件);}Overridepublic void remove(AbstractFile file) {throw new RuntimeException(无法删除文件);}
}public class Folder extends AbstractFile{private ArrayListAbstractFile files;public Folder(String fileName) {files new ArrayList();this.fileName fileName;}Overridepublic void display() {System.out.println(打开 this.fileName 文件夹);for (AbstractFile file : files) {file.display();}}Overridepublic void add(AbstractFile file) {this.files.add(file);}Overridepublic void remove(AbstractFile file) {this.files.remove(file);}
}4.3.4 组合模式的优缺点
优点缺点1.可以清楚地定义分层次的复杂对象表示对象的全部或部分层次1.在增加新构件时很难对容器中的构件类型进行限制2.客户端可以一致地使用一个组合结构或其中单个对象不必关心处理的是单个对象还是整个组合结构2.不是所有方法在叶子节点中都可以使用3.增加新的容器构件和叶子构件都很方便符合开闭原则
4.3.5 组合模式的适用场景 在具有整体和部分的层次结构中希望通过一种方式忽略整体与部分的差异客户端可以一致地对待它们 在一个使用面向对象语言开发的系统中需要处理一个树形结构 在一个系统中能够分离出叶子对象和容器对象而且它们的类型不固定需要增加一些新的类型
4.3.6 组合模式的类型
透明组合模式 定义抽象构件中声明了所有用于管理成员对象的方法包括add()、remove()以及getChild()等方法。
优点确保所有的构件类都有相同的接口客户端一致对待所有对象。
缺点不够安全因为叶子对象和容器对象在本质上是有区别的。
安全组合模式 定义抽象构件Component中没有声明任何用于管理成员对象的方法在Composite类中声明与实现这些方法
优点优点是安全对于叶子对象客户端不可能调用到这些方法
缺点不够透明客户端不能完全针对抽象编程必须有区别地对待叶子构件和容器构件