JAVA知识体系之设计模式篇

1、设计原则

1.1 开闭原则

  一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。以书店卖书为例:
在这里插入图片描述

public interface IBook {

    String getName();

    int getPrice();

    String getAuthor();
}
public class NovelBook implements IBook {

    private String name;

    private int price;

    private String author;


    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public int getPrice() {
        return this.price;
    }

    @Override
    public String getAuthor() {
        return this.author;
    }

    public NovelBook(String name, int price, String author) {
        this.name = name;
        this.price = price;
        this.author = author;
    }
}
public class BookStore {

    private final static List<IBook> bookList = new ArrayList<>();

    static {
        bookList.add(new NovelBook("《天龙八部》", 100, "金庸"));
        bookList.add(new NovelBook("《巴黎圣母院》", 200, "雨果"));
        bookList.add(new NovelBook("《悲惨世界》", 300, "雨果"));
        bookList.add(new NovelBook("《金瓶梅》", 400, "兰陵笑笑生"));
    }

    public static void main(String[] args) {
        NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
        numberFormat.setMaximumFractionDigits(2);
        System.out.println("-----------书店卖出去的书籍记录如下:-----------");
        for (IBook book : bookList) {
            System.out.println("书籍名称:" + book.getName() + "\t书籍作者:" + book.getAuthor()
                    + "\t书籍价格:" + numberFormat.format(book.getPrice() / 100.0) + "元");
        }
    }
}

运行结果:

-----------书店卖出去的书籍记录如下:-----------
书籍名称:《天龙八部》	书籍作者:金庸	书籍价格:¥100.00元
书籍名称:《巴黎圣母院》	书籍作者:雨果	书籍价格:¥200.00元
书籍名称:《悲惨世界》	书籍作者:雨果	书籍价格:¥300.00元
书籍名称:《金瓶梅》	书籍作者:兰陵笑笑生	书籍价格:¥400.00

  假设现在需要打折,有以下几种方案:
  在IBook上新增加一个方法getOffPrice(),专门用于进行打折处理,所有的实现类实现该方法。但是这样修改的后果就是,实现类NovelBook要修改,BookStore中的main方法也修改。因此,该方案否定。
  修改NovelBook类中的方法,直接在getPrice()中实现打折处理。该方法在项目有明确的章程(团队内约束)或优良的架构设计时,是一个非常优秀的方法,但是该方法还是有缺陷的。例如采购书籍人员也是要看价格的,由于该方法已经实现了打折处理价格,因此采购人员看到的也是打折后的价格,会因信息不对称而出现决策失误的情况。因此,该方案也不是一个最优的方案。
  增加一个子类OffNovelBook,覆写getPrice方法,高层次的模块(也就是static静态模块 区)通过OffNovelBook类产生新的对象,完成业务变化对系统的最小化开发。好办法,修改也少,风险也小。

public class OffNovelBook extends NovelBook {
    public OffNovelBook(String _name, int _price, String _author) {
        super(_name, _price, _author);
    }
    //覆写销售价格
    @Override
    public int getPrice() {
        //原价
        int selfPrice = super.getPrice();
        int offPrice = 0;
        if (selfPrice > 4000) {
            //原价大于40元,则打9折
            offPrice = selfPrice * 90 / 100;
        } else {
            offPrice = selfPrice * 80 / 100;
        }
        return offPrice;
    }
}

修改BookStore静态代码块,进行打折

public class BookStore {

    private final static List<IBook> bookList = new ArrayList<>();

    static {
        bookList.add(new OffNovelBook("《天龙八部》", 3200, "金庸"));
        bookList.add(new OffNovelBook("《巴黎圣母院》", 5600, "雨果"));
        bookList.add(new OffNovelBook("《悲惨世界》", 3500, "雨果"));
        bookList.add(new OffNovelBook("《金瓶梅》", 4300, "兰陵笑笑生"));
    }

    public static void main(String[] args) {
        NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
        numberFormat.setMaximumFractionDigits(2);
        System.out.println("-----------书店卖出去的书籍记录如下:-----------");
        for (IBook book : bookList) {
            System.out.println("书籍名称:" + book.getName() + "\t书籍作者:" + book.getAuthor()
                    + "\t书籍价格:" + numberFormat.format(book.getPrice() / 100.0) + "元");
        }
    }
}

运行结果:

-----------书店卖出去的书籍记录如下:-----------
书籍名称:《天龙八部》	书籍作者:金庸	书籍价格:¥25.60元
书籍名称:《巴黎圣母院》	书籍作者:雨果	书籍价格:¥50.40元
书籍名称:《悲惨世界》	书籍作者:雨果	书籍价格:¥28.00元
书籍名称:《金瓶梅》	书籍作者:兰陵笑笑生	书籍价格:¥38.70

1.2 单一职责原则

  一个类应该有且仅有一种原因引起改变。

1.3 里式替换原则

  所有引用基类的地方必须能透明地使用其子类的对象。

1.4 接口隔离原则

  客户端不应该依赖它不需要的接口。一个类对另一个类的依赖应该建立在最小的接口上。

1.5 最小知道原则(迪米特法则)

  一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。以清点学生人数为例(反例):
在这里插入图片描述

public class Teacher {
    //老师对学生发布命令,清一下女生
    public void command(GroupLeader groupLeader) {
        List listGirls = new ArrayList();
        //初始化女生
        for (int i = 0; i < 20; i++) {
            listGirls.add(new Girl());
        }
        //告诉体育委员开始执行清查任务
        groupLeader.countGirls(listGirls);
    }
}
public class GroupLeader {
    //清查女生数量
    public void countGirls(List<Girl> listGirls) {
        System.out.println("女生数量是:" + listGirls.size());
    }
}
public class Girl {
}
public class Client {

    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.command(new GroupLeader());
    }
}

运行结果:

女生数量是:20

  迪米特法则告诉我们一个类只和朋友类交流,但是我们刚刚定义的commond方法却与Girl类有了交流,声明了一个List<Girls>动态数组,也就是与一个陌生的类Girl有了交流, 这样就破坏了Teacher的健壮性。方法是类的一个行为,类竟然不知道自己的行为与其他类产生依赖关系,这是不允许的,严重违反了迪米特法则,需要进行优化:
在这里插入图片描述

public class Teacher {
    //老师对学生发布命令,清一下女生
    public void command(GroupLeader groupLeader) {
        //告诉体育委员开始执行清查任务
        groupLeader.countGirls();
    }
}
public class GroupLeader {

    private List<Girl> listGirls;

    public GroupLeader(List<Girl> listGirls) {
        this.listGirls = listGirls;
    }

    //清查女生数量
    public void countGirls() {
        System.out.println("女生数量是:" + listGirls.size());
    }
}
public class Client {

    public static void main(String[] args) {

        List<Girl> listGirls = new ArrayList<>();
        //初始化女生
        for (int i = 0; i < 20; i++) {
            listGirls.add(new Girl());
        }

        Teacher teacher = new Teacher();
        teacher.command(new GroupLeader(listGirls));
    }
}

运行结果:

女生数量是:20

  对程序进行了简单的修改,把Teacher中对List<Girl>的初始化移动到了场景类中,同时在GroupLeader中增加了对Girl的注入,避开了Teacher类对陌生类Girl的访问,降低了系统间的耦合,提高了系统的健壮性。

1.6 依赖倒置原则

  程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。以司机开车为例(反例):

public class Driver {
    //司机的主要职责就是驾驶汽车
    public void drive(Benz benz) {
        benz.run();
    }
}
public class Benz {
    //汽车肯定会跑
    public void run() {
        System.out.println("奔驰汽车开始运行...");
    }
}
public class Client {
    public static void main(String[] args) {
        Driver zhangSan = new Driver();
        Benz benz = new Benz();
        //张三开奔驰车
        zhangSan.drive(benz);
    }
}

运行结果:

奔驰汽车开始运行...

  通过以上的代码,完成了司机开动奔驰车的场景,到目前为止,这个司机开奔驰车的项目没有任何问题。但是如果我们在一段貌似磐石的程序上加上一块小石头:张三司机不仅要开奔驰车,还要开宝马车,这样就无法实现了,因为张三没有开宝马车的方法?一个拿有C驾照的司机竟然只能开奔驰车而不能开宝马车,这也太不合理了!在 现实世界都不允许存在这种情况,何况程序还是对现实世界的抽象,我们的设计出现了问题:司机类和奔驰车类之间是紧耦合的关系,其导致的结果就是系统的可维护性和可读性大大降低。根据依赖倒置原则优化后:

在这里插入图片描述

public class Driver {

    private ICar car;

    //司机的主要职责就是驾驶汽车
    public void drive() {
        car.run();
    }

    public void setCar(ICar car) {
        this.car = car;
    }
}
public interface ICar {

    void run();
}
public class Benz implements ICar{
    //汽车肯定会跑
    @Override
    public void run() {
        System.out.println("奔驰汽车开始运行...");
    }
}
public class BMW implements ICar {
    //宝马车当然也可以开动了
    @Override
    public void run() {
        System.out.println("宝马汽车开始运行...");
    }
}
public class Client {
    public static void main(String[] args) {
        Driver zhangSan = new Driver();
        //张三开奔驰车
        zhangSan.setCar(new Benz());
        zhangSan.drive();
        //张三开宝妈车
        zhangSan.setCar(new BMW());
        zhangSan.drive();
    }
}

运行结果:

奔驰汽车开始运行...
宝马汽车开始运行...

2、单例模式

在这里插入图片描述

2.1 饿汉模式

/**
 * 饿汉模式
 * 优点:线程安全,调用时效率高
 * 缺点:不管是否使用都创建对象,可能造成资源浪费
 */
package singleton;

public class Hungry {

    private Hungry(){}
    
    private static Hungry hungry = new Hungry();
    
    public static Hungry getInstance(){
        return hungry;
    }
}

2.2 懒汉模式

/**
 * 非线程安全的懒汉模式
 * 优点:调用时才创建对象,不会浪费资源
 * 缺点:非线程安全
 */
package singleton;

public class LazyNotSafe {

    private LazyNotSafe(){}
    
    private static LazyNotSafe lazyNotSafe;
    
    public static LazyNotSafe getInstance(){
        if(lazyNotSafe == null){
            lazyNotSafe = new LazyNotSafe();
        }
        return lazyNotSafe;
    }
}

2.3 加锁懒汉模式

/**
 * 线程安全的懒汉模式
 * 优点:线程安全
 * 缺点:方法锁,效率较低
 */
package singleton;

public class LazySync{

    private LazySync(){}
    
    private static LazySync lazySync;
    
    public static synchronized LazySync getInstance(){
        if(lazySync == null){
            lazySync = new LazySync();
        }
        return lazySync;
    }
}

2.4 双重检查锁

/**
 * 双重检查锁懒汉模式,线程安全,效率较高
 * 优点:线程安全,效率较高
 * 注意:lazyDoubleLock对象需要加volatile关键字,禁止JVM指令重排,否则可能导致返回未创建好的对象
 */
package singleton;

public class LazyDoubleLock {

    private LazyDoubleLock(){}
    
    private static volatile LazyDoubleLock lazyDoubleLock;
    
    public static LazyDoubleLock getInstance(){
        if(lazyDoubleLock == null){
            synchronized (LazyDoubleLock.class){
                if(lazyDoubleLock == null){
                    lazyDoubleLock = new LazyDoubleLock();
                }
            }
        }
        return lazyDoubleLock;
    }
}

2.5 静态内部类

/**
 * 静态内部类
 * 优点:线程安全,效率较高,
 * 缺点:
 */
package singleton;
import java.io.ObjectStreamException;
import java.io.Serializable;

public class StaticInner implements Serializable {
    
    private StaticInner(){
        //构造器判断,防止反射攻击
        if(InnerInstance.STATIC_INNER != null){
            throw new IllegalStateException();
        }
    }

    private Object readResolve() throws ObjectStreamException {
        return InnerInstance.STATIC_INNER;
    }

    public static StaticInner getInstance(){
        return InnerInstance.STATIC_INNER;
    }
    
    private static class InnerInstance{
        private static final StaticInner STATIC_INNER = new StaticInner();
    }
}

2.6 枚举

/**
 * 枚举
 * 优点:都是
 * 缺点:写起来不习惯
 */
package singleton;

public enum  EnumSingleton {
    INSTANCE;
    public EnumSingleton getInstance(){
        return INSTANCE;
    }
}

3、工厂模式

public interface IMilk {
}
public class Mengniu implements IMilk {

    public Mengniu(){
        System.out.println("生产蒙牛");
    }
}
public class Jindian implements IMilk {

    public Jindian() {
        System.out.println("生产金典");
    }
}
public class Telunsu implements IMilk {

    public Telunsu() {
        System.out.println("生产特仑苏");
    }
}

3.1 简单工厂模式

在这里插入图片描述

public class SimpleMilkFactory {

    public IMilk createMilk(String name) {
        if ("Telunsu".equals(name)) {
            return new Telunsu();
        } else if ("Jindian".equals(name)) {
            return new Jindian();
        } else if ("Mengniu".equals(name)) {
            return new Mengniu();
        } else {
            System.out.println("不支持生产");
            return null;
        }
    }
}
public class SimpleFactoryDemo {

    public static void main(String[] args) {
        SimpleMilkFactory simpleMilkFactory = new SimpleMilkFactory();
        IMilk mengniu = simpleMilkFactory.createMilk("Mengniu");
        IMilk jindian = simpleMilkFactory.createMilk("Jindian");
        IMilk telunsu = simpleMilkFactory.createMilk("Telunsu");
    }
}

运行结果:

生产蒙牛
生产金典
生产特仑苏

3.2 工厂方法模式

在这里插入图片描述

public interface IMethodMilkFactory {

    IMilk createMilk();
}
public class JindianMilkFactory implements IMethodMilkFactory {

    @Override
    public IMilk createMilk() {
        return new Jindian();
    }
}
public class MengniuMilkFactory implements IMethodMilkFactory {

    @Override
    public IMilk createMilk() {
        return new Mengniu();
    }
}
public class TelunsuMilkFactory implements IMethodMilkFactory {

    @Override
    public IMilk createMilk() {
        return new Telunsu();
    }
}
public class MethodFactoryDemo {

    public static void main(String[] args) {
        IMethodMilkFactory jindianMilkFactory = new JindianMilkFactory();
        jindianMilkFactory.createMilk();
        IMethodMilkFactory mengniuMilkFactory = new MengniuMilkFactory();
        mengniuMilkFactory.createMilk();
        IMethodMilkFactory telunsuMilkFactory = new TelunsuMilkFactory();
        telunsuMilkFactory.createMilk();
    }
}

运行结果:

生产蒙牛
生产金典
生产特仑苏

4、代理模式

public interface ITarget {

    void doSomething();
}
public class Target implements ITarget{

    @Override
    public void doSomething() {
        System.out.println("目标对象执行任务");
    }
}

4.1 静态代理

在这里插入图片描述

public class StaticProxy implements ITarget {

    private Target target;

    public StaticProxy(Target target) {
        this.target = target;
    }

    @Override
    public void doSomething() {
        System.out.println("代理对象执行任务");
        target.doSomething();
    }
}
public class StaticProxyDemo {

    public static void main(String[] args) {
        Target target = new Target();
        ITarget staticProxy = new StaticProxy(target);
        staticProxy.doSomething();
    }
}

运行结果:

代理对象执行任务
目标对象执行任务

4.2 动态代理

4.2.1 JDK动态代理

public class JdkDynamicInvocationHandler implements InvocationHandler {

    private Object object;

    public JdkDynamicInvocationHandler(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("代理对象执行任务");
        Object result = method.invoke(this.object, args);
        return result;
    }
}
public class JdkDynamicDemo {

    public static void main(String[] args) {
        Target target = new Target();
        ITarget proxy = (ITarget)Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), new JdkDynamicInvocationHandler(target));
        proxy.doSomething();
    }
}

运行结果:

代理对象执行任务
目标对象执行任务

4.2.2 CGLIB动态代理

public class CglibMethodInterceptor implements MethodInterceptor {

    private Object object;

    public CglibMethodInterceptor(Object object) {
        this.object = object;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("代理对象执行任务");
        Object result = method.invoke(object, objects);
        return result;
    }
}
public class CglibDynamicDemo {

    public static void main(String[] args) {

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Target.class);
        enhancer.setCallback(new CglibMethodInterceptor(new Target()));
        Target target = (Target)enhancer.create();
        target.doSomething();
    }
}

执行结果:

代理对象执行任务
目标对象执行任务

5、策略模式

在这里插入图片描述

public interface Pay {

    void pay();
}
public class AliPay implements Pay {

    @Override
    public void pay() {
        System.out.println("支付宝支付");
    }
}
public class WeChatPay implements Pay {

    @Override
    public void pay() {
        System.out.println("微信支付");
    }
}
public class QuickPassPay implements Pay {

    @Override
    public void pay() {
        System.out.println("云闪付支付");
    }
}
public class StrategyContext {

    private Pay pay;

    public StrategyContext (Pay pay) {
        this.pay = pay;
    }

    public void dealPay() {
        pay.pay();
    }
}
public class StrategyDemo {

    public static void main(String[] args) {

        StrategyContext aliPayStrategyContext = new StrategyContext(new AliPay());
        aliPayStrategyContext.dealPay();

        StrategyContext weChatPayStrategyContext = new StrategyContext(new WeChatPay());
        weChatPayStrategyContext.dealPay();

        StrategyContext quickPassPayStrategyContext = new StrategyContext(new QuickPassPay());
        quickPassPayStrategyContext.dealPay();
    }

}

运行结果:

支付宝支付
微信支付
云闪付支付

6、模板方法模式

在这里插入图片描述

public abstract class AbstractTemplate {

    public void init(){
        System.out.println("执行初始化方法");
    }

    abstract void doSomething1();

    public void hookMethod(){}

    abstract void doSomething2();

    public void destroy() {
        System.out.println("执行结束方法");
    }

    public void template() {

        init();

        doSomething1();

        hookMethod();

        doSomething2();

        destroy();
    }
}
public class TemplateObjectA extends AbstractTemplate {
    @Override
    public void doSomething1() {
        System.out.println("模板A执行方法1");
    }

    @Override
    public void hookMethod() {
        System.out.println("模板A执行钩子方法");
    }

    @Override
    public void doSomething2() {
        System.out.println("模板A执行方法2");
    }
}
public class TemplateObjectB extends AbstractTemplate {
    @Override
    void doSomething1() {
        System.out.println("模板B执行方法1");
    }

    @Override
    void doSomething2() {
        System.out.println("模板B执行方法2");
    }
}
public class TemplateDemo {

    public static void main(String[] args) {
        TemplateObjectA templateObjectA = new TemplateObjectA();
        TemplateObjectB templateObjectB = new TemplateObjectB();
        templateObjectA.template();
        System.out.println("-----");
        templateObjectB.template();
    }
}

运行结果:

执行初始化方法
模板A执行方法1
模板A执行钩子方法
模板A执行方法2
执行结束方法
-----
执行初始化方法
模板B执行方法1
模板B执行方法2
执行结束方法

7、原型模式

@Data
public class ProtoObject implements Cloneable, Serializable {

    private List<String> list = new ArrayList<>();

    public List<String> getList() {
        return list;
    }

    @Override
    public ProtoObject clone() throws CloneNotSupportedException {
        return (ProtoObject) super.clone();
    }

    public ProtoObject deepClone() {
        ProtoObject protoObject = null;
        try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("protoObject"));
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("protoObject"))) {
            oos.writeObject(this);
            protoObject = (ProtoObject)ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return protoObject;
    }
}
public class PrototypeDemo {

    public static void main(String[] args) throws CloneNotSupportedException {
        ProtoObject protoObject = new ProtoObject();
        ProtoObject protoObjectCommon = protoObject.clone();
        ProtoObject protoObjectDeep = protoObject.deepClone();
        System.out.println("克隆后赋值原型对象list");
        protoObject.getList().add("A");
        System.out.println("原型对象:" + protoObject);
        System.out.println("浅克隆结果:" + protoObjectCommon);
        System.out.println("深克隆结果:" + protoObjectDeep);
    }
}

运行结果:

克隆后赋值原型对象list
原型对象:ProtoObject(list=[A])
浅克隆结果:ProtoObject(list=[A])
深克隆结果:ProtoObject(list=[])

8、责任链模式

在这里插入图片描述

public abstract class AbstractChain {

    private AbstractChain nextChain;

    abstract void doSomethingBefore(String request);

    abstract void doSomethingAfter(String request);

    public void handler(String request) {
        doSomethingBefore(request);
        AbstractChain chain = getNextChain();
        if (chain != null) {
            chain.handler(request);
        }
        doSomethingAfter(request);
    }

    public AbstractChain getNextChain() {
        return nextChain;
    }

    public void setNextChain(AbstractChain nextChain) {
        this.nextChain = nextChain;
    }
}
public class ConcreteHandlerA extends AbstractChain {

    @Override
    void doSomethingBefore(String request) {
        System.out.println("ConcreteHandlerA doSomethingBefore " + request);
    }

    @Override
    void doSomethingAfter(String request) {
        System.out.println("ConcreteHandlerA doSomethingAfter " + request);
    }
}
public class ConcreteHandlerB extends AbstractChain {

    @Override
    void doSomethingBefore(String request) {
        System.out.println("ConcreteHandlerB doSomethingBefore " + request);
    }

    @Override
    void doSomethingAfter(String request) {
        System.out.println("ConcreteHandlerB doSomethingAfter " + request);
    }
}
public class ConcreteHandlerC extends AbstractChain {

    @Override
    void doSomethingBefore(String request) {
        System.out.println("ConcreteHandlerC doSomethingBefore " + request);
    }

    @Override
    void doSomethingAfter(String request) {
        System.out.println("ConcreteHandlerC doSomethingAfter " + request);
    }
}
public class ChainDemo {

    public static void main(String[] args) {
        ConcreteHandlerA concreteHandlerA = new ConcreteHandlerA();
        ConcreteHandlerB concreteHandlerB = new ConcreteHandlerB();
        ConcreteHandlerC concreteHandlerC = new ConcreteHandlerC();
        concreteHandlerA.setNextChain(concreteHandlerB);
        concreteHandlerB.setNextChain(concreteHandlerC);
        concreteHandlerA.handler("request");
    }
}

运行结果:

ConcreteHandlerA doSomethingBefore request
ConcreteHandlerB doSomethingBefore request
ConcreteHandlerC doSomethingBefore request
ConcreteHandlerC doSomethingAfter request
ConcreteHandlerB doSomethingAfter request
ConcreteHandlerA doSomethingAfter request

9、委派模式

在这里插入图片描述

public interface IEmployee {

    void doing(String task);
}
public class EmployeeA implements IEmployee {

    protected String name;

    public EmployeeA(String name){
        this.name = name;
    }

    @Override
    public void doing(String task) {
        System.out.println("我是员工A,我擅长"+name+",现在开始做"+task+"工作");
    }
}
public class EmployeeB implements IEmployee {

    protected String name;

    public EmployeeB(String name){
        this.name = name;
    }
    @Override
    public void doing(String task) {
        System.out.println("我是员工B,我擅长"+name+",现在开始做"+task+"工作");
    }
}
public class Leader implements IEmployee {

    HashMap<String,IEmployee> map = new HashMap<>();

    public Leader(){
        map.put("登录",new EmployeeA("开发"));
        map.put("登录页面",new EmployeeB("UI"));
    }

    @Override
    public void doing(String task) {
        map.get(task).doing(task);
    }
}
public class DelegateDemo {

    public static void main(String[] args) {
        new Leader().doing("登录");
        new Leader().doing("登录页面");
    }
}

运行结果:

我是员工A,我擅长开发,现在开始做登录工作
我是员工B,我擅长UI,现在开始做登录页面工作

10、装饰器模式

在这里插入图片描述

public interface Shape {

    void draw();
}
public class Circle implements Shape {

    @Override
    public void draw() {
        System.out.println("Shape: Circle");
    }
}
public class Rectangle implements Shape {

    @Override
    public void draw() {
        System.out.println("Shape: Rectangle");
    }
}
public abstract class ShapeDecorator implements Shape {

    protected Shape decoratedShape;

    public ShapeDecorator(Shape decoratedShape){
        this.decoratedShape = decoratedShape;
    }
}
public class RedShapeDecorator extends ShapeDecorator {

    public RedShapeDecorator(Shape decoratedShape) {
        super(decoratedShape);
    }

    @Override
    public void draw() {
        decoratedShape.draw();
        setRedBorder(decoratedShape);
    }

    private void setRedBorder(Shape decoratedShape){
        System.out.println("Border Color: Red");
    }
}
public class DecoratorDemo {

    public static void main(String[] args) {
        Shape circle = new Circle();
        ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
        ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
        //Shape redCircle = new RedShapeDecorator(new Circle());
        //Shape redRectangle = new RedShapeDecorator(new Rectangle());
        System.out.println("Circle with normal border");
        circle.draw();

        System.out.println("\nCircle of red border");
        redCircle.draw();

        System.out.println("\nRectangle of red border");
        redRectangle.draw();
    }
}

运行结果:

Circle with normal border
Shape: Circle

Circle of red border
Shape: Circle
Border Color: Red

Rectangle of red border
Shape: Rectangle
Border Color: Red

11、观察者模式

在这里插入图片描述

public class Subject {

    private List<Observer> observers = new ArrayList<>();

    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyAllObservers();
    }

    public void attach(Observer observer){
        observers.add(observer);
    }

    public void notifyAllObservers(){
        for (Observer observer : observers) {
            observer.update();
        }
    }
}
public abstract class Observer {

    protected Subject subject;

    public abstract void update();
}
public class BinaryObserver extends Observer {

    public BinaryObserver(Subject subject) {
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println("Binary String: " + Integer.toBinaryString(subject.getState()));
    }
}
public class OctalObserver extends Observer{

    public OctalObserver(Subject subject){
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println( "Octal String: " + Integer.toOctalString(subject.getState()));
    }
}
public class HexaObserver extends Observer{

    public HexaObserver(Subject subject){
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() );
    }
}
public class ObserverDemo {
    public static void main(String[] args) {
        Subject subject = new Subject();
        new HexaObserver(subject);
        new OctalObserver(subject);
        new BinaryObserver(subject);

        System.out.println("First state change: 15");
        subject.setState(15);
        System.out.println("Second state change: 10");
        subject.setState(10);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值