模板设计模式和代理模式

导读:本篇文章讲解 模板设计模式和代理模式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、基于抽象类的模板设计模式:

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式。
下面是一个完整的模板模式超类的定义
:
/**
 * 基类声明为抽象类的原因是
 * 其子类必须实现其操作
 */
abstract class AbstractClass {
    /**
     * 模板方法,被声明为final以免子类改变这个算法的顺序
     */
    final void templateMethod() {
    }
    /**
     * 具体操作延迟到子类中实现
     */
    abstract void primitiveOperation1();
    abstract void primitiveOperation2();
    /**
     * 具体操作且共用的方法定义在超类中,可以被模板方法或子类直接使用
     */
    final void concreteOperation() {
        // 实现
    }
    /**
     * 钩子方法是一类"默认不做事的方法"
     * 子类可以视情况决定要不要覆盖它们。
     */
    void hook() {
        // 钩子方法
    }
}

扩展上述类,引入”钩子方法;超类实现:

abstract class CaffeineBeverage {
    final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        // 如果顾客想要饮料我们才调用加料方法
        if (customerWantsCondiments()){
            addCondiments();
        }
    }
    abstract void brew();
    abstract void addCondiments();
    void boilWater() {
        System.out.println("Boiling water");
    }
    void pourInCup() {
        System.out.println("Pouring into cup");
    }
    /**
     * 钩子方法
     * 超类中通常是默认实现
     * 子类可以选择性的覆写此方法
     * @return
     */
    boolean customerWantsCondiments() {
        return true;
    }
}
子类实现
:
class Tea extends CaffeineBeverage {
    void brew() {
        System.out.println("Steeping the tea");
    }
    void addCondiments() {
        System.out.println("Adding Lemon");
    }
}
class Coffee extends CaffeineBeverage {
    void brew() {
        System.out.println("Dripping Coffee through filter");}
    void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }
    /**
     * 子类覆写了钩子函数,实现自定义功能
     * @return
     */
    public boolean customerWantsCondiments() {
        String answer = getUserInput();
        if (answer.equals("y")) {
            return true;
        }else {
            return false;
        }
    }
    private String getUserInput() {
        String answer = null;
        System.out.println("您想要在咖啡中加入牛奶或糖吗 (y/n)?");
        Scanner scanner = new Scanner(System.in);
        answer = scanner.nextLine();
        return answer;
    }
}

现实生活中的例子:用代码描述喝咖啡

a.把水烧开 b.将咖啡导入顾客杯子中 c.将咖啡倒入顾客杯子中 d.加糖和牛奶

public class Coffee{
    //一键启动按钮,点这个按钮就能出一杯咖啡
    public void prepareRecipe(){
        boilWater();
        brewCoffeeBag();
        pourInCup();
        addSugarAndMilk();
    }
}

现在不想喝咖啡,想点一杯茶

class Tea{
    public void prepareRecipe(){
        boilWater();
        steepTeaBag();
        pourInCup();
        addLemon();
    }
}

出现的问题:1. 代码出现大量重复(烧水,倒入杯子这两个方法对于所有热饮,大家都是通用的)

2.假设每当扩展一种新的热饮,上述代码全得重写一遍。不方便扩展。

解决问题:将热饮设计为一个父类CaffineBeverage

Coffee extends CaffeineBeverage

Tea extends CaffeineBeverage

烧水和倒入杯子操作子类就可直接使用。对于制作饮品的具体流程,对于顾客来说是不可见的

abstract class CaffeineBeverage{
    //制作流程是标准化的,封装到父类中
    //子类只有使用权不能修改
    public final void prepareRecipe(){
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
    //对于浸泡和加调味品来说,不同子类实现细节不同,延迟到子类中去具体实现
    public abstract void brew();
    public abstract  void addCondiments();
    public void pourInCup(){
    }
}
class Coffee extends CaffeineBeverage{
    @Override
    public void brew() {
        System.out.println("brew coffee bag");
    }
    @Override
    public void addCondiments() {
        System.out.println("add sugar and milk");
    }
}
class Tea extends CaffeineBeverage{
    @Override
    public void brew() {
        System.out.println("steep tea bag");
    }
    @Override
    public void addCondiments() {
        System.out.println("add lemon");
    }
}

代码中的细节解释:要保证所有加盟店的饮品在不同门店的味道都是相同的,就需要把制作流程prepareRecipe()封装到父类中,子类只能使用不能修改!

final修饰的方法子类只能使用,不能修改。

对于咖啡和茶来说,泡茶泡咖啡,加奶加柠檬就得具体子类去实现。–父类中无法实现,延迟到具体子类中实现–抽象方法

子类只需要关心子类独有的方法实现即可。共同的方法拿来即用

父类封装了核心方法(算法),子类只能使用不能修改,对于核心方法来说就是一种保护

要扩展一个新的子类,非常容易。

public boolean isCustomerWantsCondiments(){
    return true;
}

钩子方法(hook)–加糖和牛奶,有的顾客就不要。–子类来决定

对于父类来说,制作饮品的最后一步默认都是加调味品

如果有的子类可以选择不加,覆写此方法即可。

模板设计模式和代理模式

二、代理设计模式:(代购)

代理设计模式是基于接口的

代理设计就是为其他对象提供一种代理以控制对这个对象的访问。

一个接口两个实现类,一个是真实业务类,另一个是辅助真实业务的代理类

最终将真实业务传递给代理类来完成整个业务的实现

举例:

顾客:真正付钱的人(提出问题)

代购:帮助买东西(辅助解决真实问题)

class ProxySubject implements ISubject{
    private ISubject realSubject;
    public ProxySubject(ISubject subject){
        this.realSubject = subject;
    }
    public void preHandle(){
        System.out.println("买飞机票去看漂亮妹妹~");
    }
    @Override
    public void buyComputer() {
        preHandle();
        //付钱这个操作是由真实业务来处理的
        this.realSubject.buyComputer();
        postHandle();
    }
    public void postHandle() {
        System.out.println("再回国");
    }
}

代理模式的本质:所有的真实业务操作都会有一个与之辅助的工具类(功能类)共同完成。

代理模式在JavaEE中有着广泛的应用。EJB、WebService、Spring等技术都是代理模式的应用。

模板设计模式和代理模式

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/110918.html

(0)

相关推荐

半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!