设计模式 -- 工厂、代理、单例

工厂模式

工厂模式就是将客户端的new操作解耦到第三方(工厂类)

  • 简单工厂模式 -- Spring-BeanFactory

特点:

一个抽象产品类(接口)

多个具体产品类(实现接口)

一个工厂类(进行new操作)-- 客户端通过工厂类来获取具体实例

例:生产电脑

interface Computer {
    void printComputer();
}
//多个具体产品类
class Mac implements Computer {
    public void printComputer() {
        System.out.println("This is a mac");
    }
}
class AlienWare implements Computer {
    public void printComputer() {
        System.out.println("This is a AlienWare");
    }
}

//工厂类,将所有产生Computer对象实例的操作解耦到工厂类中
class Factory {
    //构造方法私有化,只能在该类中实例化对象
    private Factory(){};
    public static Computer getNewComputer(String str) {
        Computer computer = null;
        if(str.equals("mac")){
            computer = new Mac();
        }
        else if(str.equals("alienWare")){
            computer = new AlienWare();
        }
        return computer;
    }
}

public class Test {
    public static void main(String[] args) {
        System.out.println("请输入你要的电脑型号:");
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        //静态方法直接通过类名来调用
        Computer computer = Factory.getNewComputer(str);
        computer.printComputer();
    }

}
  • 工厂方法模式 -- Spring-FactoryBean

特点:

一个产品抽象类(接口)

多个具体产品类(实现接口)

一个工厂抽象类(针对抽象产品类)

多个具体工厂类(每个产品家族拥有自己的工厂)

//抽象产品类
interface Computer {
    void printComputer ();
}
//各具体产品类
class Mac implements Computer {
    public void printComputer (){
        System.out.println("This is a mac");
    }
}
class AlienWare implements Computer {
    public void printComputer (){
        System.out.println("This is a AlienWare");
    }
}
//抽象工厂类
interface Factory {
    Computer createComputer();
}
//各具体工厂类(产品族)
class msFactory implements Factory {
    public Computer createComputer(){
        return new AlienWare();
    }
}
class macFactory implements Factory{
    public Computer createComputer() {
        return new Mac();
    }
}

public class Test {
    public static void main(String[] args) {
        Factory factory = new msFactory();
        Computer computer = factory.createComputer();
        computer.printComputer();
    }
}

注意:定义一个用来创建对象的接口,让子类决定实际用一个类。针对每个产品(产品族)提供一个工厂类,客户端需要判断使用哪个工厂。

  • 抽象工厂模式

多个产品线混合,产品线的组合(暂时了解即可)

代理模式 -- Spring  AOP

特点:两个子类共同实现一个接口,其中一个子类负责真实业务实现,另外一个子类完成辅助真实业务主题的操作。

例子:买口红

interface ISubject {
    void buyLipstick();
}
//真实操作的子类
class realSubject implements ISubject {
    public void buyLipstick() {
        System.out.println("买个mac");
    }
}
//代理类
class proxySubject implements ISubject {
    //代理需要知道真实的客户
    private ISubject realSubject;
    public proxySubject(ISubject subject){
        //与真实用户建立联系
        this.realSubject = subject;
    }
    public void before(){
        System.out.println("拿钱,排队");
    }
    public void after(){
        System.out.println("发货,验收");
    }
    public void buyLipstick() {
        //辅助操作
        this.before();
        //真实业务的操作
        this.realSubject.buyLipstick();
        //辅助操作
        this.after();
    }
}

public class Test {
    public static void main(String[] args) {
        //产生一个代理类,并且与真实类产生联系
        ISubject subject = new proxySubject(new realSubject());
        subject.buyLipstick();
    }
}

注意:真实客户不用知道代理的存在,只要能完成操作即可。而代理类必须要知道真实类的存在,即和真实类有关联。(类似于现实生活中的代购)

单例模式

单例模式:一个类只能产生一个实例化对象。

实现单例的一般步骤:

  1. 构造方法私有化(从源头上防止外部类实例化对象)
  2. 类的内部new出对象(private static final)
  3. 通过静态的get方法得到该对象
  • 饿汉式单例
//饿汉式单例
class SingLeton{
    //在类中实例化该类的唯一对象
    private static final SingLeton SINGLETON = new SingLeton();
    //构造方法私有化,使得类外不能实例化对象
    private SingLeton(){};
    //通过该静态方法使得外部类可以有该类的唯一一个对象
    public static SingLeton getSingLeton(){
        return SINGLETON;
    }
}
  • 懒汉式单例
//懒汉式单例
class Sing_Leton{
    private static Sing_Leton SING_LETON = null;
    //构造方法私有化
    private Sing_Leton(){};
    public static Sing_Leton getSing_Leton(){
        //如果是第一次,产生对象,如果对象已产生,直接返回
        if(null == SING_LETON){
            SING_LETON = new Sing_Leton();
        }
        return SING_LETON;
    }
}

注意:此时,懒汉式单例存在线程安全问题。

总结抽象类与接口的区别:

注意:优先使用接口,避免单继承局限。

猜你喜欢

转载自blog.csdn.net/Sun_GLL/article/details/86522796