设计模式总结-

1、单例模式

定义:指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点。属于创建型模式。

饿汉式单例 被反射、序列化破坏
懒汉式单例 被反射、序列化破坏
容器式单例 被反射、序列化破坏
枚举式单例不会被反射、序列化破坏

在静态块中有map存放 map.put(“name”,枚举值),反序列化也是通过这个拿到对象,所以不会被序列化破坏
枚举单例内部不让通过反射来创建对象Constructor.newInstance(Constructor.java:417) 会直接抛出异常

1.1 饿汉式单例

优点:执行效率高,性能高,没有任何的锁
缺点:某些情况下回造成内存浪费。(类的数量没法控制的时候,类在加载的时候就初始化了,即使用不到也会被初始化,就会造成内存的浪费)。
代码实现:

public class HungrySingleton {
    private static final HungrySingleton singleton = new HungrySingleton();
    private HungrySingleton() {
    }
    public static HungrySingleton getSingleton() {
        return singleton;
    }
}

1.2 懒汉式单例

优点:节省内存
缺点:线程不安全,如果多个线程同时调用创建单例的方法,会创建多个对象
代码实现:以下代码已加上synchronized关键字,可以保证线程安全

public class LazySimpleSingleton {
    private static LazySimpleSingleton singleton = null;
    private LazySimpleSingleton() {
    }
    public synchronized static LazySimpleSingleton getSingleton() {
        if (singleton == null) {
            singleton = new LazySimpleSingleton();
        }
        return singleton;
    }
}

1.3 双重检索单例

优点:性能高了,线程安全了
缺点:可读性难度大,代码不优雅
代码实现:

public class LazyDoubleCheckSingleton {
    //这里添加volatile关键字 可以避免指令重排序造成的线程紊乱问题
    private volatile static LazyDoubleCheckSingleton singleton = null;
    private LazyDoubleCheckSingleton() {
    }
    public LazyDoubleCheckSingleton getSingleton() {
        //检查是否要阻塞
        if (singleton == null) {
            synchronized (LazyDoubleCheckSingleton.class) {
                //检查是否为空
                if (singleton == null) {
                    singleton = new LazyDoubleCheckSingleton();
                    //这里会发生指令重排序
                }
            }
        }
        return singleton;
    }
}

指令重排序:1.开辟堆空间 2.对开辟的空间进行初始化 3.将内存空间的地址赋值给变量(instance) 这三步走完才是创建完一个对象。如果不加volatile关键字,可能这三步就会错乱,导致指令重排序。

1.4 静态内部类单例

优点:利用了JAVA本身的语法特点,性能高,避免了内存浪费
缺点:能够本反射破坏
代码实现:

public class LazyStaticInnerClassSingleton {
    private LazyStaticInnerClassSingleton() {
        //避免反射破坏
        if (InnerClassSingleton.innerClassSingleton != null) {
            throw new RuntimeException("不能非法访问");
        }
    }
    public static LazyStaticInnerClassSingleton getSingleton() {
        return InnerClassSingleton.innerClassSingleton;
    }
    //在这里使用的时候才会调用静态内部类 InnerClassSingleton.innerClassSingleton;
    private static class InnerClassSingleton {
        private static final LazyStaticInnerClassSingleton innerClassSingleton = new LazyStaticInnerClassSingleton();
    }
}

1.5 枚举单例

优点:最优雅的写法,提供性能,防止反射破坏单例,防止线程破坏单例,被官方推荐。
缺点:不能大面积创建对象,容器造成内存浪费,序列化会破坏单例。
代码实现:

public enum EnumSingleton {
    INSTANCE;
    private Object data;
    public static EnumSingleton getInstance() {
        return INSTANCE;
    }
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }
}

枚举单例内部不让通过反射来创建对象,Constructor.newInstance(Constructor.java:417) 会直接抛出异常

1.6 容器式单例

优点:解决了大面积创建对象的问题,不会造成内存浪费,是对枚举单例的优化,是spring ioc使用的单例方式。
缺点:线程不安全
代码实现:
以下代码中已加入双重检索,从而可以避免线程安全的问题。

public class ContainerSingleton {

    private static Map containerMap = new ConcurrentHashMap();

    private ContainerSingleton() {
    }

    public static Object getInstance(String className) {
        Object instance = null;
        if (!containerMap.containsKey(className)) {
            synchronized (ContainerSingleton.class){
                if (!containerMap.containsKey(className)){
                    try {
                        Class<?> aClass = Class.forName(className);
                        instance = aClass.newInstance();
                        containerMap.put(className, instance);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return instance;
        } else {
            return containerMap.get(className);
        }
    }
}

1.7 序列化单例

优点:避免序列化破坏单例
缺点:
代码实现:

public class SerializableSingleton {

    private static final SerializableSingleton singleton = new SerializableSingleton();

    private SerializableSingleton() {
    }

    public static SerializableSingleton getSingleton() {
        return singleton;
    }

    //加入此方法可以解决被序列化破坏的单例
    //具体要看一下 ObjectInputStream中的readObject()方法 下的 readObject0方法中的 checkResolve方法中的readOrdinaryObject方法   
// if (obj != null && handles.lookupException(passHandle) ==null
 //&& desc.hasReadResolveMethod()
    //在这个方法处理之后就不会再重新创建了 就直接返回singleton对象了
    private Object readResolve() {
        return singleton;
    }

}

反序列化是不走构造函数的,是直接使用字节码重组的

1.8 ThreadLocal单例

在同一个线程下单例,不同的线程下会创建不同的对象
代码实现:

public class ThreadLocalSingleton {
    private static final ThreadLocal threadLocalSingleton = new ThreadLocal() {
        @Override
        protected ThreadLocalSingleton initialValue() {
            return new ThreadLocalSingleton();
        }
    };
    private ThreadLocalSingleton() {
    }
    public static ThreadLocalSingleton getInstance() {
        return threadLocalSingleton.get();
    }
}

1.9 单例模式学习重点

  1. 私有构造器
  2. 保存线程安全
  3. 延迟加载
  4. 防止序列化反序列化破坏单例
  5. 防止反射攻击单例

1.10 单例模式在源码中的应用

Spring中AbstractFactoryBean类下的getObject方法
Mybatis中ErrorContext
ServletContext、ServletConfig、ApplicationContext、DBPool、BeanFactory、Runtime、Rpc

2、工厂模式

2.1 简单工厂模式

定义:指由一个工厂对象决定创建出哪一种产品类的实例,属于创建型模式,但是不属于23中设计模式。

使用场景:

源码中实现场景:

代码实现:

设计模式总结

public interface ICourse {

    void record();

}

public class CourseImpl implements ICourse {

    @Override
    public void record() {
        System.out.println("正在学习简单工厂模式");
    }
}

public class JavaCourse implements ICourse{
    @Override
    public void record() {
        System.out.println("正在学习JAVA课程");
    }
}

public class SimpleFactory {
    public ICourse create(Class clazz) {
        try {
            if (clazz != null) {
                return (ICourse) clazz.newInstance();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

2.2 工厂方法模式

定义:是指定义一个创建对象的接口,让实现这个接口类来决定实例化哪个类,工厂方法模式让类的实例化推迟到子类中进行,属于创建型模式。
使用场景:

源码中实现场景:

代码实现:

设计模式总结

public interface ICourse {

    void record();
}
public class JavaCourse implements ICourse {

    @Override
    public void record() {
        System.out.println("正在学习JAVA 工厂方法模式");
    }


}

public class PythonCourse implements ICourse {

    @Override
    public void record() {
        System.out.println("正在学习Python 工厂方法模式");
    }
}


public interface ICourseFactory {

    ICourse create();
}

public class JavaCourseFactory implements ICourseFactory {


    @Override
    public ICourse create() {
        return new JavaCourse();
    }
}

public class PythonCourseFactory implements ICourseFactory {

    @Override
    public ICourse create() {
        return new PythonCourse();
    }
}

public class MethodFactoryMain {
    public static void main(String[] args) {
        ICourseFactory factory = new JavaCourseFactory();
        ICourse iCourse = factory.create();
        iCourse.record();
    }
}

2.3 抽象工厂模式

定义:指提供创建一系列相关或相互依赖对象的接口,无序指定它们具体的类,属于创建型模式。
使用场景:

源码中实现场景:

代码实现:

设计模式总结

public interface ICourse {

    void record();

}

public interface INote {

    void write();
}

public interface IVideo {
    void video();
}

public interface ICourseFactory {

    INote createNote();

    ICourse createCource();

    IVideo createVideo();

}


public class JavaCourse implements ICourse {

    @Override
    public void record() {
        System.out.println("course 正在学习JAVA 抽象工厂模式");
    }


}


public class JavaNote implements INote {
    @Override
    public void write() {
        System.out.println("note 正在学习抽象工厂方法模式");
    }
}


public class JavaVideo implements IVideo {
    @Override
    public void video() {
        System.out.println("video 正在学习抽象工厂模式");
    }
}

public class JavaCourseFactory implements ICourseFactory {

    @Override
    public INote createNote() {
        return new JavaNote();
    }

    @Override
    public ICourse createCource() {
        return new JavaCourse();
    }

    @Override
    public IVideo createVideo() {
        return new JavaVideo();
    }
}

public class PythonCourse implements ICourse{
    @Override
    public void record() {
        System.out.println("PythonCourse正在学习抽象工厂模式");
    }
}

public class PythonNote implements INote{
    @Override
    public void write() {
        System.out.println("python 正在学习抽象工厂方法");
    }
}

public class PythonVideo implements IVideo{
    @Override
    public void video() {
        System.out.println("PythonVideo 正在学习抽象工厂模式");

    }
}

public class PythonFactory implements ICourseFactory{
    @Override
    public INote createNote() {
        return new PythonNote();
    }

    @Override
    public ICourse createCource() {
        return new PythonCourse();
    }

    @Override
    public IVideo createVideo() {
        return new PythonVideo();
    }
}

public class AbstractFactoryMain {
    public static void main(String[] args) {
        ICourseFactory factory = new JavaCourseFactory();
        factory.createCource().record();
        factory.createNote().write();
        factory.createVideo().video();


        ICourseFactory pythonFactory = new PythonFactory();
        pythonFactory.createCource().record();
        pythonFactory.createNote().write();
        pythonFactory.createVideo().video();

    }
}

3、代理模式

指为其他对象提供一种代理,以控制对这个对象的访问,代理对象和目标对象之间起到中介作用,属于结构性模式。

3.1 静态代理模式

代码实现:

设计模式总结

public interface IPerson {

    void findFriend();
}

public class Uncle implements IPerson {

    private XiaoPengYou xiaoPengYou;

    public Uncle(XiaoPengYou xiaoPengYou) {
        this.xiaoPengYou = xiaoPengYou;
    }

    @Override
    public void findFriend() {
        System.out.println("小朋友找到了叔叔");
        xiaoPengYou.findFriend();
        System.out.println("叔叔帮助小朋友找到了小伙伴");
    }
}

public class XiaoPengYou implements IPerson {
    @Override
    public void findFriend() {
        System.out.println("小朋友想要找个小伙伴");
    }
}

public class StaticProxyMain {
    public static void main(String[] args) {
        Uncle uncle = new Uncle(new XiaoPengYou());
        uncle.findFriend();
    }
}

3.2 动态代理模式

spring中的代理选择原则:

  1. 当Bean有实现接口时,Spring就会用jdk动态代理
  2. 当Bean没有实现接口时,Spring就会用cglib动态代理
  3. Spring可以通过配置强制使用cglib,只需要Spring配置文件中添加以下代码

Cglib动态代理代理和JDK动态代理区别

  1. Cglib是继承的方式,覆盖父类的方法,JDK采用的是实现的方式,必须要求代理的目标对象一定要实现一个接口,通过生成字节码重组成一个新的类。
  2. JDKProxy对于用户而言,依赖更强,调用也更复杂。Cglib对目标类没有任何要求
  3. Cglib效率更高,性能也更高,底层没有用到反射。JDKProxy生成逻辑较为简单,执行效率低,每次都要用到反射。
  4. Cglib目标代理类不能有final修饰的方法,忽略final修饰的方法。

3.2.1 jdk动态代理

实现原理:

  1. 动态生成源码.java文件
  2. Java文件输出到磁盘,保存为文件Proxy0.java
  3. 把.java文件编译成Proxy0.class文件
  4. 把生成的.class文件加载到JVM中
  5. 返回新的代理对象

代码实现:

设计模式总结

public interface IPerson {

    void study();

}

public class Student implements IPerson {
    @Override
    public void study() {
        System.out.println("学生想学习动态代理");
    }
}
public class Teacher implements IPerson {
    @Override
    public void study() {
        System.out.println("老师想学习动态代理");
    }
}
public class ProxyClient implements InvocationHandler {

    private Object target;

    public Object getTarget(Object target) {
        this.target = target;
        Class<?> clazz = target.getClass();
        //类加载器  Object   this代表当前类(就是实现InvocationHandler这个接口的类)
        return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
    }


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

        Object invoke = method.invoke(this.target, args);

        return invoke;
    }
}

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

        ProxyClient proxyClient = new ProxyClient();
//        IPerson target = (IPerson)proxyClient.getTarget(new Student());
//        target.study();
//
//        IPerson target1 = (IPerson)proxyClient.getTarget(new Teacher());
//        target1.study();

        //jdk代理再被jdk代理 start 使用同一个InvocationHandler
//        IPerson target2 = (IPerson)proxyClient.getTarget(new Student());
//        target2.study();
//        IPerson target3 = (IPerson)proxyClient.getTarget(target2);
//        target3.study();
        //jdk代理再被jdk代理 end

        //jdk代理再被jdk代理 start 使用不同的InvocationHandler
        ProxyClient proxyClient1 = new ProxyClient();
        IPerson target4 = (IPerson) proxyClient.getTarget(new Student());
        target4.study();
        IPerson target5 = (IPerson) proxyClient1.getTarget(target4);
        target5.study();
        //jdk代理再被jdk代理 end


    }
}

3.2.2 cglib动态代理

实现原理:

代码实现:

设计模式总结

public interface IPerson {

    void study();

}

public class Student {
    public void study() {
        System.out.println("学生想学习动态代理");
    }
}
public class Teacher {
    public void study() {
        System.out.println("老师想学习动态代理");
    }
}
public class CgLibProxy implements MethodInterceptor {

    public Object getInstance(Class clazz) {
        //cglib 创建代理对象的类库
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }


    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object result = methodProxy.invokeSuper(o, objects);
        return result;
    }
}
public class CglibProxyMain {
    public static void main(String[] args) {
        CgLibProxy cgLibProxy = new CgLibProxy();
        Student instance = (Student) cgLibProxy.getInstance(Student.class);
        instance.study();

        Teacher instance1 = (Teacher) cgLibProxy.getInstance(Teacher.class);
        instance1.study();

    }
}

3.3 动态代理相关问题

3.3.1 我们的代理类还能再被代理吗?

1.jdk代理后的类再次被jdk代理?
jdk不能再次被jdk代理,因为会造成handler调用死循环。如果使用不同的实现InvocationHandler的代理类是可以的,mybatis中的多重插件就是这么做的
2.jdk代理后的类再次被cglib代理?
jdk生成的代理类是final,cglib生成的代理类是要去继承目标类的,final修饰的类不能被继承,所以不能被代理
3.cglib代理后的类再次被cglib代理?
会报方法名重复 Duplicate method name “newInstance” with signature
4.cglib代理后的类再次被jdk代理?
类的签名已经改变,没有目标方法了
总结,只有jdk代理能再次被jdk代理,必须使用不同的InvocationHandler,其他都不可以

3.3.2 什么样类不能被代理?

1.对于jdk,必须有接口实现
2.final修飾的方法不能被cglib代理
3.方法不是public的

3.3.3 接口能够被代理吗?

接口能被代理,比如mybatis中的dao接口就是这样做

4、模板方法模式

定义:又叫模板模式,是指定义一个算法的骨架,并允许子类为其中的一个或者多个步骤提供实现。模板方法使得子类不改变算法结构的情况下,重新定义算法的某些步骤。属于行为型设计模式
使用场景:

  1. 一次性实现算法不变的部门,将可变的部分留给子类去实现。
  2. 各子类中公共的行为被提取出来并集中到一个公共的父类中,避免代码重复。

源码中实现场景:

  1. jdbcTemplate
  2. AbstractList 中的get方法
  3. HttpServlet中的doGet方法和doPost方法
  4. mybatis中的BaseExecutor下的doQuery方法

优点
1.利用模板模式将相同的处理逻辑代码放到抽象父类中,可以提高代码复用性
2.将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性
3.把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,符合代开闭原则。

缺点
1.类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类数量增加,间接的增加了系统实现的复杂度
2.继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要修改一遍
代码实现:

public class JavaCourse extends AbstractCoursr {
    @Override
    public boolean needCheckHomework() {
        return true;
    }

    @Override
    protected void checkHomework() {
        System.out.println("检查JAVA作业");
    }
}

public abstract class AbstractCoursr {


    public void createCourse() {
        //1.发布预习资料
        postPrepareData();
        //2.制作PPT
        makePPT();
        //3.直播上课
        videoInClass();
        //4.上传课堂笔记
        uploadNote();
        //5.布置作业
        assignHomework();
        if (needCheckHomework()) {
            //6.检查作业
            checkHomework();
        }

    }


    public abstract boolean needCheckHomework();

    protected abstract void checkHomework();

    protected void assignHomework() {
        System.out.println("布置作业");
    }

    protected void uploadNote() {
        System.out.println("上传课堂笔记");
    }

    protected void videoInClass() {
        System.out.println("直播上课");
    }

    protected void makePPT() {
        System.out.println("制作PPT");
    }

    protected void postPrepareData() {
        System.out.println("发布预习资料");
    }

}


public class TemplateMain {

    public static void main(String[] args) {

        JavaCourse javaCourse = new JavaCourse();
        javaCourse.createCourse();

    }

}

5、装饰器模式

定义:也叫包装模式,是指在不改变原对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案。属于结构型模式。
使用场景:

  1. 用户扩展一个类的功能,或给一个类添加附加职责。
  2. 动态的给一个对象添加功能,这些功能可以再动态的撤销。

源码中的实现:

  1. InputStream BufferedInputStream 就是实际使用到的装饰器模式
  2. BufferedReader FileReader
  3. mybatis中的Cache的实现就是装饰器,同时也是委派模式

优点
1.装饰器是继承的有力补充,比继承灵活,不改变原有的对象的情况下,动态的给一个对象扩展功能
2.通过使用不同装饰器类以及这些装饰类的排列组合,可实现不同效果
3.装饰器完全遵守开闭原则

缺点
1.会出现更多的代码,更多的类,增加程序复杂性
2.动态装饰时,多层装饰会更复杂。

装饰器模式和代理模式对比
1.装饰器模式是一种特殊的代理模式
2.装饰器模式强调自身的功能扩展
3.代理模式强调的是代理过程的控制

代码实现:

设计模式总结

public abstract class BatterCake {

    public abstract String name();

    public abstract Double getPrice();


}

public class BaseBatterCake extends BatterCake {
    @Override
    public String name() {
        return "煎饼";
    }

    @Override
    public Double getPrice() {
        return 5D;
    }
}

public class Decorator extends BatterCake {
    private BatterCake batterCake;

    public Decorator(BatterCake batterCake) {
        this.batterCake = batterCake;
    }

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

    @Override
    public Double getPrice() {
        return this.batterCake.getPrice();
    }
}
public class EggDecorator extends Decorator {

    public EggDecorator(BatterCake batterCake) {
        super(batterCake);
    }

    @Override
    public Double getPrice() {
        return super.getPrice() + 1;
    }

    @Override
    public String name() {
        return super.name() + "加1个鸡蛋";
    }
}
public class SuguaDecorator extends Decorator {
    public SuguaDecorator(BatterCake batterCake) {
        super(batterCake);
    }

    @Override
    public String name() {
        return super.name() + "加1根肠";
    }

    @Override
    public Double getPrice() {
        return super.getPrice() + 2;
    }
}
public class DecoratorMain {
    public static void main(String[] args) {

        BatterCake batterCake;

        batterCake = new BaseBatterCake();

        batterCake = new EggDecorator(batterCake);

        batterCake = new SuguaDecorator(batterCake);

        System.out.println(batterCake.name() + " " + batterCake.getPrice());


    }

}

6、策略模式

定义:又叫政策模式,将定义的算法家族分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。,可以避免多重分支的if。。。else。。。和switch语句。属于行为型模式。

使用场景:

  1. 假如系统中有很多类,而他们的区别仅仅在于它们的行为不同。
  2. 一个系统需要动态的在不同的算法中选择一种。
  3. 需要屏蔽算法规则。

源码中的实现:

  1. Arrays中public static void parallelSort(T[] a, int fromIndex, int toIndex,Comparator<? super T> cmp)
  2. TreeMap中的compare
  3. Spring中的Resource

优点:
符合开闭原则
避免使用多重条件转移语句 if else switch
提供算法的安全性和保密性

缺点:
客户端必须知道所有的策略,并且自行决定使用哪一个策略类
代码中产生非常多的策略类,增加维护难度

代码实现:

设计模式总结

public interface IStradegy {
    void algorithm();
}
public class Context {

    private IStradegy iStradegy;

    public Context(IStradegy iStradegy) {
        this.iStradegy = iStradegy;
    }

    public void algorithm() {
        this.iStradegy.algorithm();
    }

}
public class ConcreteStrategyA implements IStradegy {
    @Override
    public void algorithm() {
        System.out.println("ConcreteStrategyA");
    }
}
public class ConcreteStrategyB implements IStradegy {
    @Override
    public void algorithm() {
        System.out.println("ConcreteStrategyB");
    }
}
public class StradegyMain {

    public static void main(String[] args) {

        Context context = new Context(new ConcreteStrategyA());
        context.algorithm();

    }
}

7、委派模式

定义:又叫委托模式,基本的作用就是负责任务的调度和任务的分配,将任务的分配和执行分离开来,可以看做是一种特殊情况下的静态代理的全权代理。不属于GOF 23种设计模式之一。属于行为型模式。
源码中实现:

JVM中的双亲委派 一层一层的往上去找
类 public abstract class ClassLoader

方法  protected Class<?> loadClass(String name, boolean resolve)

反射中的
类public final class Method
方法public Object invoke(Object obj, Object... args)

spring中
BeanDefinition
BeanDefinitionParserDelegate

DispatcherServlet中的
doDispatch();

委派模式和代理模式区别
委派模式是行为型模式,代理模式是结构型模式
委派模式注重的是任务派遣,注重结果,代理模式注重的是代码增强,注重过程。
委派模式是一种特殊的静态代理,相当于全权代理。

代码实现:

设计模式总结

public interface IEmployee {
    void doing(String task);
}

public class Boss {

    public void commond(String task, Leader leader) {
        leader.doing(task);
    }
}

public class EmployeeA implements IEmployee {
    @Override
    public void doing(String task) {
        System.out.println("员工A开始做事");
    }
}

public class EmployeeB implements IEmployee {
    @Override
    public void doing(String task) {
        System.out.println("员工B开始做事");
    }
}
public class Leader implements IEmployee {

    private Map map = new ConcurrentHashMap();

    public Leader() {
        map.put("爬虫", new EmployeeA());
        map.put("管理", new EmployeeB());
    }


    @Override
    public void doing(String task) {
        if (!map.containsKey(task)) {
            System.out.println("超出能力范围");
        } else {
            map.get(task).doing(task);
        }

//        if ("爬虫".equals(task)){
//            new EmployeeA().doing(task);
//        } else if ("管理".equals(task)){
//            new  EmployeeB().doing(task);
//        } else {
//            System.out.println("不符合用人规范");
//        }
    }
}

public class DelegateMain {

    public static void main(String[] args) {

        Boss boss = new Boss();
        boss.commond("爬虫", new Leader());

    }

}
展开阅读全文

页面更新:2024-05-05

标签:模式   子类   线程   反射   接口   对象   工厂   代码   方法   动态

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top