设计模式设计模式

一些常见的设计模式总结

2018-08-19  本文已影响155人  SHAN某人

1.工厂模式

Spring中的应用:
BeanFactory 构造对象

// student.xml
<bean id="studentBean" class="advanced.Student">
    <property name="name" value="Tom"/>
    <property name="age" value="18"/>
</bean>
public static void main(String[] args) throws Exception {
    BeanFactory bf = new ClassPathXmlApplicationContext("student.xml");
    Student studentBean = (Student) bf.getBean("studentBean");

    studentBean.print();
}

2. 建造者设计模式

建设者设计模式是属于创建对象模式三剑客的第一种模式。该模式用于简化复杂对象的构造。要理解这个概念,想象一个说明程序员简历的对象。在这个对象中,我们想存储个人信息(名字,地址等)以及技术信息(知识语言,已实现的项目等)。该对象的构造可能如下所示:

// with constructor
Programmer programmer = new Programmer("first name", "last name", "address Street 39", "ZIP code", "City", "Country", birthDateObject, new String[] {"Java", "PHP", "Perl", "SQL"}, new String[] {"CRM system", "CMS system for government"});
// or with setters
Programmer programmer = new Programmer();
programmer.setName("first name");
programmer.setLastName("last name");
// ... multiple lines after
programmer.setProjects(new String[] {"CRM system", "CMS system for government"});

应用了建造者模式,可以把对象属性设置过程抽象隐藏,交给内置的建造者去做,这时候创建一个对象看起来像这样:

public class Test {
    public static void main(String[] args) {
        Person person = new Person.Builder().setIdAndName(123,"shan").setSex("男")
                .build();
        System.out.println(person);
    }
}
public class Person {
    private Integer  id;
    private String  name;
    private String  sex;


    public static class Builder{
        private Person  person;
        public Builder(){
            person = new Person();
        }

        public Builder  setIdAndName(Integer id,String name){
            person.id = id;
            person.setName(name);
            return this;
        }

        public Builder  setSex(String sex){
            person.setSex(sex);
            return this;
        }

        public Person build(){
            return person;
        }

    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

Spring中的应用:

public class BeanDefinitionBuilder {
       /**
    * The {@code BeanDefinition} instance we are creating.
    */
  private AbstractBeanDefinition beanDefinition;
 
  // ... some not important methods for this article
 
  // Some of building methods
  /**
    * Set the name of the parent definition of this bean definition.
    */
  public BeanDefinitionBuilder setParentName(String parentName) {
    this.beanDefinition.setParentName(parentName);
    return this;
  }
 
  /**
    * Set the name of the factory method to use for this definition.
    */
  public BeanDefinitionBuilder setFactoryMethod(String factoryMethod) {
    this.beanDefinition.setFactoryMethodName(factoryMethod);
    return this;
  }
 
  /**
    * Add an indexed constructor arg value. The current index is tracked internally
    * and all additions are at the present point.
    * @deprecated since Spring 2.5, in favor of {@link #addConstructorArgValue}
    */
  @Deprecated
  public BeanDefinitionBuilder addConstructorArg(Object value) {
    return addConstructorArgValue(value);
  }
 
  /**
    * Add an indexed constructor arg value. The current index is tracked internally
    * and all additions are at the present point.
    */
  public BeanDefinitionBuilder addConstructorArgValue(Object value) {
    this.beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(
                    this.constructorArgIndex++, value);
    return this;
  }
 
  /**
    * Add a reference to a named bean as a constructor arg.
    * @see #addConstructorArgValue(Object)
    */
  public BeanDefinitionBuilder addConstructorArgReference(String beanName) {
    this.beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(
                    this.constructorArgIndex++, new RuntimeBeanReference(beanName));
    return this;
  }
 
  /**
    * Add the supplied property value under the given name.
    */
  public BeanDefinitionBuilder addPropertyValue(String name, Object value) {
    this.beanDefinition.getPropertyValues().add(name, value);
    return this;
  }
 
  /**
    * Add a reference to the specified bean name under the property specified.
    * @param name the name of the property to add the reference to
    * @param beanName the name of the bean being referenced
    */
  public BeanDefinitionBuilder addPropertyReference(String name, String beanName) {
    this.beanDefinition.getPropertyValues().add(name, new RuntimeBeanReference(beanName));
    return this;
  }
 
  /**
    * Set the init method for this definition.
    */
  public BeanDefinitionBuilder setInitMethodName(String methodName) {
    this.beanDefinition.setInitMethodName(methodName);
    return this;
  }
 
  // Methods that can be used to construct BeanDefinition
  /**
    * Return the current BeanDefinition object in its raw (unvalidated) form.
    * @see #getBeanDefinition()
    */
  public AbstractBeanDefinition getRawBeanDefinition() {
    return this.beanDefinition;
  }
 
  /**
    * Validate and return the created BeanDefinition object.
    */
  public AbstractBeanDefinition getBeanDefinition() {
    this.beanDefinition.validate();
    return this.beanDefinition;
  }
}

3. 装饰者模式

装饰模式的核心在于抽象装饰类的设计,其典型代码如下所示:

class Decorator implements Component{
       private Component component;  //维持一个对抽象构件对象的引用
       public Decorator(Component component)   { //注入一个抽象构件类型的对象
              this.component=component;
       }
       public void operation(){
              component.operation();  //调用原有业务方法
       }
}

在抽象装饰类Decorator中定义了一个Component类型的对象component,维持一个对抽象构件对象的引用,并可以通过构造方法或Setter方法将一个Component类型的对象注入进来,同时由于Decorator类实现了抽象构件Component接口,因此需要实现在其中声明的业务方法operation(),需要注意的是在Decorator中并未真正实现operation()方法,而只是调用原有component对象的operation()方法,它没有真正实施装饰,而是提供一个统一的接口,将具体装饰过程交给子类完成。

在Decorator的子类即具体装饰类中将继承operation()方法并根据需要进行扩展,典型的具体装饰类代码如下:

class ConcreteDecorator extends Decorator{
       // 构造注入
       public ConcreteDecorator(Component  component){
              super(component);
       }
       public void operation() {
              super.operation();  //调用原有业务方法
              addedBehavior();  //调用新增业务方法
       }

     //新增业务方法
       public  void addedBehavior(){    
         ……
       }
}

Java I/O 使用了装饰者模式来实现。以 InputStream 为例,

实例化一个具有缓存功能的字节流对象时,只需要在 FileInputStream 对象上再套一层 BufferedInputStream 对象即可。

FileInputStream fileInputStream = new FileInputStream(filePath);
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

DataInputStream 装饰者提供了对更多数据类型进行输入的操作,比如 int、double 等基本类型。
移步查看装饰者模式:学好设计模式防被祭天:装饰者模式
设计模式详解——装饰者模式

上一篇 下一篇

猜你喜欢

热点阅读