java设计模式之结构型模式
1. 适配器模式(Adapter Pattern)
特点:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
使用场景:当需要使用一个现有的类,但它的接口不符合需求时;想要创建一个可复用的类,该类可以与不相关或不可预见的类协同工作。
代码示例:
interface Target {
void request();
}
class Adaptee {
public void specificRequest() {
System.out.println("Adaptee's specific request");
}
}
class Adapter extends Adaptee implements Target {
@Override
public void request() {
specificRequest();
}
}
public class AdapterPatternExample {
public static void main(String[] args) {
Target target = new Adapter();
target.request();
}
}
优点:提高了类的复用性;将目标类和适配者类解耦;增加了类的透明度和灵活性。
缺点:过多地使用适配器,会让系统非常零乱,不易整体进行把握。
2. 桥接模式(Bridge Pattern)
特点:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
使用场景:当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
代码示例:
interface Implementor {
void operationImpl();
}
class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
System.out.println("ConcreteImplementorA operation");
}
}
class ConcreteImplementorB implements Implementor {
@Override
public void operationImpl() {
System.out.println("ConcreteImplementorB operation");
}
}
abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
@Override
public void operation() {
implementor.operationImpl();
}
}
public class BridgePatternExample {
public static void main(String[] args) {
Implementor implementorA = new ConcreteImplementorA();
Abstraction abstraction = new RefinedAbstraction(implementorA);
abstraction.operation();
Implementor implementorB = new ConcreteImplementorB();
abstraction = new RefinedAbstraction(implementorB);
abstraction.operation();
}
}
优点:分离了抽象和实现,使它们可以独立变化;提高了系统的可扩展性;实现了细节对客户的透明。
缺点:增加了系统的理解和设计难度。
3. 组合模式(Composite Pattern)
特点:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
使用场景:当需要表示对象的部分-整体层次结构时;希望用户忽略组合对象与单个对象的不同,统一地使用它们时。
代码示例:
interface Component {
void operation();
}
class Leaf implements Component {
private String name;
public Leaf(String name) {
this.name = name;
}
@Override
public void operation() {
System.out.println("Leaf: " + name + " operation");
}
}
class Composite implements Component {
private List<Component> children = new ArrayList<>();
public void add(Component component) {
children.add(component);
}
public void remove(Component component) {
children.remove(component);
}
@Override
public void operation() {
for (Component component : children) {
component.operation();
}
}
}
public class CompositePatternExample {
public static void main(String[] args) {
Composite root = new Composite();
Composite branch1 = new Composite();
Leaf leaf1 = new Leaf("Leaf 1");
Leaf leaf2 = new Leaf("Leaf 2");
branch1.add(leaf1);
branch1.add(leaf2);
Composite branch2 = new Composite();
Leaf leaf3 = new Leaf("Leaf 3");
branch2.add(leaf3);
root.add(branch1);
root.add(branch2);
root.operation();
}
}
优点:定义了包含基本对象和组合对象的类层次结构;简化了客户端代码;更容易增加新类型的组件。
缺点:设计较为复杂,不容易掌握。
4. 装饰器模式(Decorator Pattern)
特点:动态地给一个对象添加一些额外的职责,比生成子类更加灵活。
使用场景:需要在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责时。
代码示例:
interface Component {
void operation();
}
class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("ConcreteComponent operation");
}
}
class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
component.operation();
}
}
class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
@Override
public void operation() {
super.operation();
System.out.println("ConcreteDecoratorA added behavior");
}
}
class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
@Override
public void operation() {
super.operation();
System.out.println("ConcreteDecoratorB added behavior");
}
}
public class DecoratorPatternExample {
public static void main(String[] args) {
Component component = new ConcreteComponent();
Component decoratedComponentA = new ConcreteDecoratorA(component);
Component decoratedComponentB = new ConcreteDecoratorB(decoratedComponentA);
decoratedComponentB.operation();
}
}
优点:比继承更灵活;可以动态地为对象添加职责;不会导致类数量的急剧增加。
缺点:装饰器模式会产生很多小对象,增加了系统的复杂性。
5. 外观模式(Facade Pattern)
特点:为子系统中的一组接口提供一个一致的界面,简化了子系统的使用。
使用场景:当需要为一个复杂的子系统提供一个简单的接口时;当客户端和子系统之间存在许多依赖关系时。
代码示例:
class SubsystemA {
public void operationA() {
System.out.println("SubsystemA operation");
}
}
class SubsystemB {
public void operationB() {
System.out.println("SubsystemB operation");
}
}
class SubsystemC {
public void operationC() {
System.out.println("SubsystemC operation");
}
}
class Facade {
private SubsystemA subsystemA;
private SubsystemB subsystemB;
private SubsystemC subsystemC;
public Facade() {
subsystemA = new SubsystemA();
subsystemB = new SubsystemB();
subsystemC = new SubsystemC();
}
public void operation() {
subsystemA.operationA();
subsystemB.operationB();
subsystemC.operationC();
}
}
public class FacadePatternExample {
public static void main(String[] args) {
Facade facade = new Facade();
facade.operation();
}
}
优点:降低了客户端与子系统的耦合度;简化了客户端的使用;对客户端隐藏了子系统的组件。
缺点:不符合开闭原则,如果要修改外观类的接口,可能会影响到所有的客户端。
5. 享元模式(Flyweight Pattern)
特点:运用共享技术有效地支持大量细粒度的对象。
使用场景:系统中存在大量相似的对象;需要节省内存或提高性能时。
代码示例:
interface Flyweight {
void operation(String extrinsicState);
}
class ConcreteFlyweight implements Flyweight {
private String intrinsicState;
public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}
@Override
public void operation(String extrinsicState) {
System.out.println("Intrinsic State: " + intrinsicState + ", Extrinsic State: " + extrinsicState);
}
}
class FlyweightFactory {
private Map<String, Flyweight> flyweights = new HashMap<>();
public Flyweight getFlyweight(String key) {
if (!flyweights.containsKey(key)) {
flyweights.put(key, new ConcreteFlyweight(key));
}
return flyweights.get(key);
}
}
public class FlyweightPatternExample {
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory();
Flyweight flyweight1 = factory.getFlyweight("A");
flyweight1.operation("State 1");
Flyweight flyweight2 = factory.getFlyweight("A");
flyweight2.operation("State 2");
Flyweight flyweight3 = factory.getFlyweight("B");
flyweight3.operation("State 3");
}
}
优点:减少了对象的创建数量,降低了系统的内存占用;提高了性能。
缺点:增加了系统的复杂性,需要分离出内部状态和外部状态。
6. 代理模式(Proxy Pattern)
特点:为其他对象提供一种代理以控制对这个对象的访问。
使用场景:当需要对目标对象进行访问控制时;当需要为目标对象添加额外的功能时。
代码示例:
interface Subject {
void request();
}
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject request");
}
}
class ProxySubject implements Subject {
private RealSubject realSubject;
public ProxySubject() {
realSubject = new RealSubject();
}
@Override
public void request() {
// 在此可以添加额外的逻辑,如权限检查等
realSubject.request();
}
}
public class ProxyPatternExample {
public static void main(String[] args) {
Subject subject = new ProxySubject();
subject.request();
}
}
优点:可以隐藏目标对象的实现细节;增强了目标对象的功能;可以对目标对象进行访问控制。
缺点:可能会导致系统的性能下降;增加了代码的复杂性。
7. 过滤器模式(Filter Pattern)
特点:使用不同的标准来过滤一组对象。
使用场景:当需要从一组对象中筛选出符合特定条件的对象时。
代码示例:
interface Filter {
boolean filter(Person person);
}
class MaleFilter implements Filter {
@Override
public boolean filter(Person person) {
return person.getGender().equals("Male");
}
}
class FemaleFilter implements Filter {
@Override
public boolean filter(Person person) {
return person.getGender().equals("Female");
}
}
class Person {
private String name;
private String gender;
public Person(String name, String gender) {
this.name = name;
this.gender = gender;
}
public String getName() {
return name;
}
public String getGender() {
return gender;
}
}
class FilterPatternExample {
public static void main(String[] args) {
List<Person> persons = new ArrayList<>();
persons.add(new Person("Alice", "Female"));
persons.add(new Person("Bob", "Male"));
persons.add(new Person("Charlie", "Male"));
Filter maleFilter = new MaleFilter();
List<Person> malePersons = filterPersons(persons, maleFilter);
Filter femaleFilter = new FemaleFilter();
List<Person> femalePersons = filterPersons(persons, femaleFilter);
}
public static List<Person> filterPersons(List<Person> persons, Filter filter) {
List<Person> result = new ArrayList<>();
for (Person person : persons) {
if (filter.filter(person)) {
result.add(person);
}
}
return result;
}
}
优点:提供了一种灵活的方式来过滤对象;易于扩展新的过滤条件。
缺点:可能会导致代码的复杂性增加,特别是在有多个过滤器组合使用的情况下。