java详细设计模式有代码

设计模式

1.七大原则

1.单一职责原则

(每个类或者每个方法只需要实现一个职责,不需要实现很多其他的功能。)在类中的方法足够多需要在类的层面遵守单一职责原则

方法遵循单一职责代码实现:

package com.example;

public class SingleResponsibility {
    public static void main(String[] args) {
        Vehicle vehicle = new Vehicle();
        vehicle.runAir("飞机");
        vehicle.runRolad("车子");
        vehicle.runWater("游艇");
     
    }
}
class Vehicle{
    public void runRolad(String vehicle){
        System.out.println(vehicle + "在公路上面运行");

    }
    public void runWater(String vehicle){
        System.out.println(vehicle + "在水中上面运行");
    }

    public void runAir(String vehicle){
        System.out.println(vehicle + "在天上运行");
    }
}

2.接口隔离原则

A通过接口B依赖于C(只要实现接口B的1,2,3方法),D通过接口B依赖于F(只需要 实现接口B的1,4,5方法),这样A就得实现所有的B接口的方法,D就得实现所有的B接口方法,导致浪费,且相关性强,所以得遵循接口最小原则,把 方法1 放在一个接口Interface1, 方法 2,3放在一个接口Interface2 ,方法4,5放在一个接口Interface3.

3.依赖倒转原则

  1. 高层模块不应该依赖低层模块,二者应该依赖其抽象(接口和抽象类)
  2. 抽象不应该依赖细节,细节(一般是java的实现类)应该依赖抽象
  3. 、依赖倒转的中心思想是面向接口编程
  4. 设计理念:以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。
  5. java里面接口或者抽象类的目的是设计好规范(不去实现),实现一定是由那个实现类去操作。
  6. 继承时遵循里氏替换原则
代码实现
有问题代码
package com.monkey.single.inversion;

public class DependenceInversion {
    public static void main(String[] args) {
        Person person = new Person();
        person.receiveMessage(new Email());

    }
}

class Email{
    public String getInfo(){
        return "email,helloWorld";
    }
}

//1.这个只可以接收邮箱的消息,不可以接收其他的比如微信,支付宝,短信的消息。
//2.我们可以来创建一个接口IReceiver(),这样Person类和接口IReceiver发生依赖
//因为Email,WeChat等等属于接收的范围,他们各自实现IReceiver接口就行,这样就发生了依赖倒转。




class Person{
//   这里是对实现类进行了依赖
    public void receiveMessage(Email email){
        System.out.println(email.getInfo());
    }


}
实现依赖倒转原则以后的代码
package com.monkey.single.inversion;

public class DependenceInversion {
    public static void main(String[] args) {
        Person person = new Person();
        person.receiveMessage(new Email());
        person.receiveMessage(new Wexin());

    }
}


interface Ireceiver{
    public String getInfo();
}


class Email implements Ireceiver{
    public String getInfo(){
        return "email,helloWorld";
    }
}

class Wexin implements Ireceiver{
    public String getInfo(){
        return "wexin,helloWorld";
    }

}

//1.这个只可以接收邮箱的消息,不可以接收其他的比如微信,支付宝,短信的消息。
//2.我们可以来创建一个接口IReceiver(),这样Person类和接口IReceiver发生依赖
//因为Email,WeChat等等属于接收的范围,他们各自实现IReceiver接口就行,这样就发生了依赖倒转。




class Person{

//    这里是对接口进行依赖,稳定性好
    public void receiveMessage(Ireceiver ireceiver){
        System.out.println(ireceiver.getInfo());
    }


}

实现接口间依赖传递的三种方式:

  1. 通过接口传递实现依赖
  2. 通过构造方法依赖传递
  3. 通过setter方法依赖传递

代码:


4.里氏替换原则

5.开闭原则

6.迪米特法原则

7.合成复用原则

经典面试题目?

  1. 在项目的实际开发中哪里使用了ocp原则? (工厂模式中有用)

  2. spring中应用了哪些设计模式,原型模式在哪里 用到?

  3. 什么是解释器设计模式?画出它的UML类图,分析各个角色是什么?

  4. spring框架中哪里使用到了解释器设计模式?并做源码级别分析

  5. 单例模式一共有几种实现方式?用代码实现,并说明各个的优点缺点。

单列设计模式有几种实现方式?

  1. 饿汉式 两种

  2. 懒汉式 三种

  3. 双重检查

  4. 静态内部类

    设计模式概念:(design pattern)是对在软件设计普遍存在(反复出现)的各种问题,提出 的一种解决方案。

使用设计模式可以使用项目具有:可扩展性,维护性,可靠性(新增一个功能对原来的功能影响不大),可复用性,效率提高等等

设计模式:

1.单例模式:

饿汉模式:
package com.monkey.sigleton;
/*
* 饿汉模式:
* 类加载就实例化,JVM保证线程安全
* 推荐使用
* 唯一缺点: 不管使用与与否,类加载就会完成实例化
*
* */
public class HungryMode {
    private static final HungryMode Instance = new HungryMode();
    private HungryMode(){};
    public static HungryMode getInstance(){
        return Instance;
    }

    public static void main(String[] args) {
        HungryMode instance = HungryMode.getInstance();
        HungryMode instance1 = HungryMode.getInstance();
        System.out.println(instance == instance1);

    }



}

懒汉模式(双重if判断):
package com.monkey.sigleton;

public class LazyModeImprove {

    private static LazyModeImprove Instance;

    private LazyModeImprove(){};

    private static LazyModeImprove getInstance(){
        if(Instance == null){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (LazyModeImprove.class){
                if(Instance == null){
                    Instance = new LazyModeImprove();
                }

            }
        }
        return  Instance;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 1000; i++) {
            new Thread(()->
                    System.out.println(Instance.getInstance())
            ).start();
        }

    }
}




懒汉模式静态内部类:
package com.monkey.sigleton;

public class LazyModeStaicInnerClass {
    private LazyModeStaicInnerClass(){};

   private static class  SingletonInstance{
        private static final LazyModeStaicInnerClass Instance = new LazyModeStaicInnerClass();

    }

    public static LazyModeStaicInnerClass getInstance(){
        return SingletonInstance.Instance;
    }


}



枚举单例模式:
package com.monkey.sigleton;

public enum EnumMode{
//    1. 可以防止反序列化,也是线程安全的
    INSTANCE;
    public void hellowWord(){
        System.out.println("hello Word");
    }

    public static void main(String[] args) {
        INSTANCE.hellowWord();

    }

}



2.策略模式(把相同行为的不同实现进行封装)

package com.monkey.strategy.improve;

public abstract class Duck {
    FlyBehavior flyBehavior;
    public Duck() {
    }
    public abstract void display();//显示鸭子信息



    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

    public void quack(){
        System.out.println("鸭子会嘎嘎叫");
    }
    public void swim(){
        System.out.println("鸭子会游戏");
    }
//    public void fly(){
//        System.out.println("鸭子会飞行");
//    }
//    improve
    public void fly(){
        if(flyBehavior !=null){
            flyBehavior.fly();
        }

    }
}



package com.monkey.strategy.improve;

public interface FlyBehavior {
    void fly(); //子类具体实现
}



package com.monkey.strategy.improve;

public class GoodFlyBehavior implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("飞翔技术高超");
    }
}



package com.monkey.strategy.improve;

public class GoodFlyBehavior implements FlyBehavior{
    @Override
    public void fly() {
        System.out.println("飞翔技术高超");
    }
}



package com.monkey.strategy.improve;

public class PekingDuck  extends Duck {

    PekingDuck(){
        flyBehavior = new BadFlyBehavior();
    }



    @Override
    public void display() {
        System.out.println("我是北京鸭");
    }
//北京鸭不能飞行,这里需要重写方法
   /* @Override
    public void fly() {
        System.out.println("北京鸭不能飞行");
    }*/
}




package com.monkey.strategy.improve;

public class ToyDuck extends Duck {


    ToyDuck(){
        flyBehavior = new BadFlyBehavior();
    }
    @Override
    public void display() {
        System.out.println("我是玩具鸭");
    }
// 需要重写父类的所有方法
 public void quack(){
    System.out.println("玩具鸭子不会嘎嘎叫");
}
    public void swim(){
        System.out.println("玩具鸭子不会游戏");
    }
//    public void fly(){
//        System.out.println("玩具鸭子不会飞行");
//    }
}


package com.monkey.strategy.improve;

public class WildDuck extends Duck {
    WildDuck(){
        flyBehavior = new GoodFlyBehavior();
    }
    @Override
    public void display() {
        System.out.println("我是野鸭子");
    }
}


3. 享元模式(Flyweight pattern)

场景应用:**数据库连接池,缓冲池,Integer的底层源码,String常量池等等。**可以解决重复对象内存浪费问题。

理解:需要的我们拿来使用,不需要的直接创建 new一个。

String str = "hello";
String s2 = new String("hello ");

**内部状态:**对象共享出来的信息,且不随享元对象的外部状态改变而改变。

**外部状态:**随环境的改变而改变,不可共享的一个状态。

public class IntegerCode {
    public static void main(String[] args) {
        Integer integer = Integer.valueOf(126);
        Integer integer1 = Integer.valueOf(126);
        System.out.println(integer == integer1);

        Integer integer2 = Integer.valueOf(128);
        Integer integer3 = Integer.valueOf(128);
        System.out.println(integer2 == integer3);

    }
}
//里面的Integer.valueOf()使用了享元模式,如果大小在[-128,127]之间使用同一个数组里面的数据,否则重新创建一个Integer类型对象,减少了内存的消耗。

4.代理模式

为一个对象提供一个替身,以控制这个对象的访问。即 通过代理对象访问目标对象。

被代理的对象可以是 远程对象,创建开销大的对象,或需要安全控制的对象。

主要有:动态代理(也叫jdk代理),静态代理,cglib代理(可以在内存动态的创建对象,不需要实现接口,属于动态代理)。

在有些情况下,我们不可以直接访问目标对象,需要通过另外一个对象进行代理访问。

静态代理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-owrRldFi-1659411175436)(C:\Users\24473\AppData\Roaming\Typora\typora-user-images\image-20220706230151861.png)]

动态代理(JDK代理)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ludHQFDo-1659411175438)(C:\Users\24473\AppData\Roaming\Typora\typora-user-images\image-20220709173609450.png)]

图片上面是复用反射机制

可以看到代理对象不用实现目标接口

其实是通过 java的反射机制实现,然后通过代理对象进行调用ITeacherDao方法。

代理对象=增强内容+原对象。
其实就是spring中的aop
    
    我们想在当前的业务逻辑下添加一些其他的处理,比如日志、校验等等,就不得不侵入原有的业务代码,尤其是在重重继承关系复杂的类中,需要增加一些内容,并不清楚会不会影响到其他功能,所以使用代理来实现需要增加的内容
package com.monkey.proxy.dynamic;

public interface IteacherDao {
    void teach();//

    String sayProxyStart(String proxyName);
}

package com.monkey.proxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactory {

    private Object target; //代理的目标对象

//    有参树构造器,对target 进行初始化
    public ProxyFactory(Object target) {
        this.target = target;
    }
    //给目标对象通过 JDK的API 生成代理对象的方法
    public Object getProxyInstace(){
//  ClassLoader loader    类加载器
//        2. Class<?> interface
//        3. InvocationHandler
//
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("jdk动态代理开始");
                Object object = method.invoke(target, args);

                return object;
            }
        });
    }
}

package com.monkey.proxy.dynamic;

import com.monkey.proxy.ITeacherDao;

public class Teacher implements IteacherDao {
    @Override
    public void teach() {
        System.out.println("老师正在授课中。。。。。。。。。。");
    }

    @Override
    public String sayProxyStart(String proxyName) {

        return proxyName;
    }


}

package com.monkey.proxy.dynamic;




public class Client {
    public static void main(String[] args) {

        Teacher target = new Teacher();

//      需要强制类型转换为ITeacherDao才可以调用到 接口里面的方法
        IteacherDao proxyInstace = (IteacherDao)new ProxyFactory(target).getProxyInstace();
        System.out.println("proxyInstace"+proxyInstace);
//      调用代理对象的方法
        proxyInstace.teach();

        String hello_proxy = proxyInstace.sayProxyStart("hello Proxy");
        System.out.println(hello_proxy);


    }
}

cglib代理

静态代理类和jdk代理都需要我们的目标对象实现一个接口,但是有些时候我们希望这个目标对象没有实现接口,可以使用目标对象的子类实现代理,这就是cglib代理。

cglib是一个强大的,高性能的代码生成包,它可以在运行期扩展java类实现java接口,(SpringAop中有使用,实现方法拦截。)

在Aop编程中如何选用代理模式:

  1. 目标对象需要实现接口,使用jdk代理(动态代理)
  2. 目标对象不需要实现接口,用cglib代理。

cglib底层是使用字节码处理框架ASM,转换字节码,并生成新的类。

ProxyFactory(代理对象需要 implements MethodInterceptor) MethodInterceptor是框架待的一个接口方法拦截,里面重写了 interceptor方法

5.模板方法模式

在一个抽象类中公开定义了一个执行它的方法模板,它的子类可以进行重写(关键的步骤)方法来实现,但调用将以抽象类中定义的方式进行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ISCrvslB-1659411189861)(C:\Users\24473\AppData\Roaming\Typora\typora-user-images\image-20220714230054147.png)]

重点

  1. 模板方法是用final修饰的不可以进行重写
  2. 里面调用了常用的其他制作方法,可以进行重写关键的方法。
  3. 关键的方法是不用写相关的实现的。
  4. 基本流程实现的相同,需要写上相关的实现。

代码实现:

package com.monkey.template;

public abstract class SoyaMilk {
//    制作豆浆模板
    final void make(){
        select();
        if(customerAddCondiments()){
            addCondiments();
        }
        soak();
        beat();

    }
    //选材料
    void select(){
        System.out.println("第一步,选择好新鲜的黄豆");
    }
    //添加不同的配料,抽象方法,子类具体实现
    abstract  void addCondiments();

    boolean customerAddCondiments(){
        return true;
    }
    //浸泡
    void soak(){
        System.out.println("第三步,黄豆进行浸泡");
    }
    void beat(){
        System.out.println("第四步,黄豆打碎");
    }
}
package com.monkey.template;

public class RedBeanSoyaMilck extends SoyaMilk{
    @Override
    void addCondiments() {
        System.out.println("加入上好的红豆豆浆");
    }
}

package com.monkey.template;

public class PureSoyaMilk extends SoyaMilk{
    @Override
    void addCondiments() {
        //纯的豆浆不用添加
    }

    @Override
    boolean customerAddCondiments() {
        //因为是纯的豆浆不用添加任何其他的东西
        return false;
    }
}

package com.monkey.template;

public class PeanutSoyaMilk extends SoyaMilk{
    @Override
    void addCondiments() {
        System.out.println("加入上好的花生豆浆");
    }
}

package com.monkey.template;

public class Client {
    public static void main(String[] args) {
        System.out.println("红豆豆浆开始制作");
        SoyaMilk soyaMilk = new RedBeanSoyaMilck();
        soyaMilk.make();
        System.out.println("花生豆浆开始制作");
        SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
        peanutSoyaMilk.make();

        System.out.println("纯豆浆开始制作");
        SoyaMilk pureSoyaMilk = new PureSoyaMilk();
        pureSoyaMilk.make();


    }
}

6.观察者模式

又叫发布-订阅模式,模型视图模式, 从属模式, 源-监听模式。

概念:**定义了一对多的依赖关系,让多个观察者同时监听某个主题对象。**主题对象在状态上发生变化,会同时通知所有观察者对象,使他们同时更新自己。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sIalrkBc-1659411203154)(C:\Users\24473\AppData\Roaming\Typora\typora-user-images\image-20220722222223344.png)]

改进观察者好处:

  1. 观察者模式设计后会心集合方式管理用户(Observer),包括register,remove,notify.
  2. 这样观察者就是一个新的公告板,不需要修改核心类WeatherData,遵守ocp原则。

JDK源码中有一个ObServable类实现了观察者模式

在这里相当于 Subject这个接口,进行管理Observer

Observable,里面的addObserver,deleteObserve,notifyObserver分别对应Subject里面的相关的方法。

Observer作用等价于我们的Observer,里面也有update方法。

只是源码是通过继承实现的,Observable里面已经实现了相关的方法实现

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;

    /** Construct an Observable with zero Observers. */

    public Observable() {
        obs = new Vector<>();
    }

    /**
     * Adds an observer to the set of observers for this object, provided
     * that it is not the same as some observer already in the set.
     * The order in which notifications will be delivered to multiple
     * observers is not specified. See the class comment.
     *
     * @param   o   an observer to be added.
     * @throws NullPointerException   if the parameter o is null.
     */
    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    /**
     * Deletes an observer from the set of observers of this object.
     * Passing <CODE>null</CODE> to this method will have no effect.
     * @param   o   the observer to be deleted.
     */
    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

    /**
     * If this object has changed, as indicated by the
     * <code>hasChanged</code> method, then notify all of its observers
     * and then call the <code>clearChanged</code> method to
     * indicate that this object has no longer changed.
     * <p>
     * Each observer has its <code>update</code> method called with two
     * arguments: this observable object and <code>null</code>. In other
     * words, this method is equivalent to:
     * <blockquote><tt>
     * notifyObservers(null)</tt></blockquote>
     *
     * @see     java.util.Observable#clearChanged()
     * @see     java.util.Observable#hasChanged()
     * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
     */
    public void notifyObservers() {
        notifyObservers(null);
    }

    /**
     * If this object has changed, as indicated by the
     * <code>hasChanged</code> method, then notify all of its observers
     * and then call the <code>clearChanged</code> method to indicate
     * that this object has no longer changed.
     * <p>
     * Each observer has its <code>update</code> method called with two
     * arguments: this observable object and the <code>arg</code> argument.
     *
     * @param   arg   any object.
     * @see     java.util.Observable#clearChanged()
     * @see     java.util.Observable#hasChanged()
     * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
     */
    public void notifyObservers(Object arg) {
        /*
         * a temporary array buffer, used as a snapshot of the state of
         * current Observers.
         */
        Object[] arrLocal;

        synchronized (this) {
            /* We don't want the Observer doing callbacks into
             * arbitrary code while holding its own Monitor.
             * The code where we extract each Observable from
             * the Vector and store the state of the Observer
             * needs synchronization, but notifying observers
             * does not (should not).  The worst result of any
             * potential race-condition here is that:
             * 1) a newly-added Observer will miss a
             *   notification in progress
             * 2) a recently unregistered Observer will be
             *   wrongly notified when it doesn't care
             */
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }

    /**
     * Clears the observer list so that this object no longer has any observers.
     */
    public synchronized void deleteObservers() {
        obs.removeAllElements();
    }

    /**
     * Marks this <tt>Observable</tt> object as having been changed; the
     * <tt>hasChanged</tt> method will now return <tt>true</tt>.
     */
    protected synchronized void setChanged() {
        changed = true;
    }

    /**
     * Indicates that this object has no longer changed, or that it has
     * already notified all of its observers of its most recent change,
     * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.
     * This method is called automatically by the
     * <code>notifyObservers</code> methods.
     *
     * @see     java.util.Observable#notifyObservers()
     * @see     java.util.Observable#notifyObservers(java.lang.Object)
     */
    protected synchronized void clearChanged() {
        changed = false;
    }

    /**
     * Tests if this object has changed.
     *
     * @return  <code>true</code> if and only if the <code>setChanged</code>
     *          method has been called more recently than the
     *          <code>clearChanged</code> method on this object;
     *          <code>false</code> otherwise.
     * @see     java.util.Observable#clearChanged()
     * @see     java.util.Observable#setChanged()
     */
    public synchronized boolean hasChanged() {
        return changed;
    }

    /**
     * Returns the number of observers of this <tt>Observable</tt> object.
     *
     * @return  the number of observers of this object.
     */
    public synchronized int countObservers() {
        return obs.size();
    }
}

public interface Observer {
    /**
     * This method is called whenever the observed object is changed. An
     * application calls an <tt>Observable</tt> object's
     * <code>notifyObservers</code> method to have all the object's
     * observers notified of the change.
     *
     * @param   o     the observable object.
     * @param   arg   an argument passed to the <code>notifyObservers</code>
     *                 method.
     */
    void update(Observable o, Object arg);
}

7.工厂模式

这里讲一下比较绕的 抽象工厂模式。
使用工厂模式可以使我们客户端调用的时候变得简单,只需要修改一个工厂模式封装好的产品就行。
例子:

  1. 人开着car,拿着ak47,吃着Bread(面包) 对应三个类
  2. 魔法精灵 开着Broom(扫把),拿着魔法棒,吃着MushRoom(蘑菇) 对应三个类
    3. 人是一个产品,魔法精灵也是产品要求如何更加简洁的增加其他的产品
  3. 可以把 形容词使用接口, 名词使用抽象类
7.1代码

Ak47


public class AK47 extends Weapon {
    public void shoot(){
        System.out.println("shoot----");
    }
}




Car


package com.monkey.factory.abstractfactory;

import com.monkey.factory.Moveable;

public class Car extends Vehicle {
    public void go(){
        System.out.println("car dididid........");
    }
}



Bread


package com.monkey.factory.abstractfactory;

public class Bread extends Food {
    public void eat(){
        System.out.println("eatBread......");
    }
}



MagicStick


package com.monkey.factory.abstractfactory;

public class MagicStick extends Weapon {
    public void shoot(){
        System.out.println("魔法棒----");
    }
}



MushRoom


package com.monkey.factory.abstractfactory;

public class MushRoom extends Food {
    public void eat(){
        System.out.println("mushroom-----");
    }
}



Broom

package com.monkey.factory.abstractfactory;

public class Broom extends Vehicle {
    public void go(){
        System.out.println("魔法世界的人开broom----");
    }


}




7.2抽象出来的三个抽象类

package com.monkey.factory.abstractfactory;

public abstract class Food {
   abstract void eat();
}




package com.monkey.factory.abstractfactory;

public abstract class Vehicle {
    abstract void go();
}



package com.monkey.factory.abstractfactory;

public abstract class Weapon {
    abstract void shoot();

}


7.3 把三个抽象类放到一个抽象类中封装
package com.monkey.factory.abstractfactory;

public abstract class AbstractFactory {
    abstract Food createFood();
    abstract Vehicle createVehicle();
    abstract Weapon createWeapon();
}


7.4 每个产品增加自己产品抽象类,继承(extends)抽象父类
7.41现代世界的人
package com.monkey.factory.abstractfactory;


public class ModernFactory  extends AbstractFactory{

    @Override
    Food createFood() {
        return new Bread();
    }

    @Override
    Vehicle createVehicle() {
        return new Car();
    }

    @Override
    Weapon createWeapon() {
        return new AK47();
    }
}


7.42魔法世界的人
package com.monkey.factory.abstractfactory;

public class MagicStickFactory extends AbstractFactory {
    @Override
    Food createFood() {
        return new MushRoom();
    }

    @Override
    Vehicle createVehicle() {
        return new Broom();
    }

    @Override
    Weapon createWeapon() {
        return new MagicStick();
    }
}

7.43客户端进行调用,修改MagicStickFactory这个产品就可以进行不同的调用
package com.monkey.factory.abstractfactory;

import com.monkey.factory.Moveable;
import com.monkey.factory.Plane;

public class Main {
    public static void main(String[] args) {
//        new Car().go();
//
//        new Plane().go();

        AbstractFactory a = new MagicStickFactory();

        Food food = a.createFood();
        food.eat();

        Weapon weapon = a.createWeapon();
        weapon.shoot();

        Vehicle vehicle = a.createVehicle();
        vehicle.go();


    }
}




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
当谈到Java设计模式,有许多经典的模式可以应用在不同的场景中。以下是几个常见的设计模式以及对应的代码示例: 1. 单例模式(Singleton Pattern): ```java public class Singleton { private static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } ``` 2. 工厂模式(Factory Pattern): ```java public interface Shape { void draw(); } public class Rectangle implements Shape { @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } } public class Circle implements Shape { @Override public void draw() { System.out.println("Inside Circle::draw() method."); } } public class ShapeFactory { public Shape getShape(String shapeType) { if (shapeType.equalsIgnoreCase("RECTANGLE")) { return new Rectangle(); } else if (shapeType.equalsIgnoreCase("CIRCLE")) { return new Circle(); } return null; } } ``` 3. 观察者模式(Observer Pattern): ```java import java.util.ArrayList; import java.util.List; public interface Observer { void update(String message); } public class ConcreteObserver implements Observer { private String name; public ConcreteObserver(String name) { this.name = name; } @Override public void update(String message) { System.out.println(name + " received message: " + message); } } public interface Subject { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(String message); } public class ConcreteSubject implements Subject { private List<Observer> observers = new ArrayList<>(); @Override public void registerObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { observers.remove(observer); } @Override public void notifyObservers(String message) { for (Observer observer : observers) { observer.update(message); } } } ``` 这些只是一些常见的设计模式和相应的代码示例,Java设计模式有很多种类,每个模式都有自己特定的应用场景。希望这些示例能为你提供一些帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有时间指导毕业设计

觉得写的好的话可以给我打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值