图解设计模式 --交给子类

代码Github连接 :https://github.com/tangbi123/Tab-Design-Pattern

一、Template Method模式

Template Method:在父类中定义处理流程的框架,在子类中实现具体处理的模式。

1、示例

在这里插入图片描述

名字说明
AbstractDisplay只实现了display方法的抽象类
CharDisplay实现了open、print、close方法的类
StringDisplay实现了open、print、close方法的类
Main测试程序行为的类

代码清单

1)AbstractDisplay

public abstract class AbstractDisplay {
    public abstract void open();
    public abstract void print();
    public abstract void close();
    public final void display(){
        open();
        for(int i = 0; i < 5; i++)
            print();
        close();
    }
}

2)CharDisplay

public class CharDisplay extends AbstractDisplay{

    private char ch;

    public CharDisplay(char ch) {
        this.ch = ch;
    }

    @Override
    public void open() {
        System.out.print("<<");
    }

    @Override
    public void print() {
        System.out.print(ch);
    }

    @Override
    public void close() {
        System.out.println(">>");
    }
}
  1. StringDisplay
public class StringDisplay extends AbstractDisplay{
    private String string;
    private int width;
    public StringDisplay(String string) {
        this.string = string;
        this.width = string.getBytes().length;
    }

    @Override
    public void open() {
        printLine();
    }

    @Override
    public void print() {
        System.out.println("|" + string + "|");
    }

    @Override
    public void close() {
        printLine();
    }

    private void printLine(){
        System.out.print("+");
        for(int i = 0; i < width; i++)
            System.out.print("-");
        System.out.println("+");
    }
}

4)main

public class main {
    public static void main(String[] args) {
        AbstractDisplay d1 = new CharDisplay('H');
        AbstractDisplay d2 = new StringDisplay("Hello world.");
        AbstractDisplay d3 = new StringDisplay("你好世界");

        d1.display();
        d2.display();
        d3.display();
    }
}

2、角色

1)AstractClass(抽象类) =》 AbstractDisplay
不仅负责实现模板方法,还负责声明在模板方法中所使用到的抽象方法。
抽象方法由子类ConcreteClass角色实现。

2)ConcreteClass(具体类) =》 CharDisplay、StringDisplay
负责具体实现AbstractClass角色中定义的抽象方法。
在这里插入图片描述

3、思路要点

1)使逻辑处理通用化
发现Bug,修改模板方法即可。

2)父类和子类协作
父类子类紧密联系,共同工作。
在子类实现父类生命的抽象方法时,必须要理解这些抽象方法被调用的时机。
在看不到父类的源代码情况,想要编写出子类是非常困难的。

3)父类与子类的一致性
子类实例,都是先保存在父类类型的变量中,然后再来调用方法。
里氏替换:无论在父类类型的变量中保存哪个子类实例,程序都可以正常工作。

4、延申:类的层次与抽象类

1)父类对子类的要求(“子类责任”)
理解类的层次,通常站在 子类 角度思考:
1、子类可以使用父类定义的方法
2、可以通过子类中增加方法以实现新的功能
3、在子类中重写父类方法可以改变程序的行为。

站在父类的角度思考:
1、期待子类去实现抽象方法
2、要求子类去实现抽象方法

2)抽象类的意义
在抽象阶段确定: 处理的流程

3)父类与子类之间的协作
父类实现方法过多: 子类轻松,但降低子类的灵活性
父类实现方法过少:子类臃肿不堪,各子类间代码重复

Template Method模式中,
父类:处理流程的定义;子类:具体的处理。
但是对于如何划分处理级别、那些处理需要由父类完成、那些处理需要交给子类负责,没有定式,都需要由负责程序设计的开发人员来决定。

Factory Method模式

父类决定实例的生成方式,但并不决定索要生成的具体的类,具体的处理全部交给子类负责。
将生成实例的框架 和 实际负责生成实例的类 解耦

1、示例

在这里插入图片描述

名字说明
frameworkProduct之定义抽象方法user的抽象类
frameworkFactory实现了create方法的抽象类
idcardIDCard实现了user方法的类
idcardIDCardFactory实现了createProduct、registerProduct方法的类
无名Main测试程序行为的类

代码清单

1)Product 接口

package Factory_Method.framework;

public abstract class Product {
    public abstract void use();
}

2)Factory 接口

package Factory_Method.framework;

public abstract class Factory {
    public final Product create(String owner){
        Product product = createProduct(owner);
        registerProduct(product);
        return product;
    }
    protected abstract Product createProduct(String owner);
    protected abstract void registerProduct(Product product);
}

3)IDCard 类

package Factory_Method.idcard;

import Factory_Method.framework.Product;

public class IDCard extends Product {
    private String owner;
    public IDCard(String owner){
        System.out.println("制作" + owner + "的ID卡");
        this.owner = owner;
    }

    public String getOwner() {
        return owner;
    }
    @Override
    public void use() {
        System.out.println("使用" + owner + "的ID卡");
    }
}

4)IDCardFactory 类

import Factory_Method.framework.Product;

import java.util.ArrayList;
import java.util.List;

public class IDCardFactory extends Factory {
    private List owner = new ArrayList();
    @Override
    protected Product createProduct(String owner) {
        return new IDCard(owner);
    }

    @Override
    protected void registerProduct(Product product) {
        owner.add(((IDCard)product).getOwner());
    }
    public List getOwner(){
        return owner;
    }
}
  1. main
package Factory_Method;

import Factory_Method.framework.Factory;
import Factory_Method.framework.Product;
import Factory_Method.idcard.IDCardFactory;

public class main {
    public static void main(String[] args) {
        Factory factory = new IDCardFactory();
        Product card1 = factory.create("小明");
        Product card2 = factory.create("小红");
        Product card3 = factory.create("小军");
        card1.use();
        card2.use();
        card3.use();
    }
}

2、角色

在这里插入图片描述
1)Product =》 Product
定义了生成实例所持有的接口(API),但具体的处理则由子类ConcreteProduct角色决定。

2)Create => Factory
负责生成Product角色的抽象类,但具体的处理由子类 ConcreteCreator角色决定。
Create角色 只知道, 只要调用Product角色和 生成实例的方法, 就可以生成Product的实例。=》(createProduct)

3)ConcreteProduct => IDCard
决定了具体的产品。

4)ConcreteCreator => IDCardFactory
负责生成具体的产品。

3、思路要点

1)框架与具体加工

2)生成实例 三种方法
createProduct 方法
1、指定其为抽象类, 子类继承,就需要实现该方法。
2、实现默认处理
3、在其中抛出异常

3)使用模式与开发人员之间的沟通
必须要理解父类中所定义的处理的框架 和 它里面所使用的抽象方法,然后阅读代码,了解这些抽象方法在子类中的实现才行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值