单例模式-工厂模式

一:单例模式

1.单例模式只能有一个实例

2.单例必须自己创建自己的唯一实例

3.单例必须给所有其他对象提供这一实例

在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例,这些应用或多或少具有资源管理器的功能。

单例模式之懒汉单例:

//0.创建自己的单例程序
class MySingle2{
    //6.2创建一个静态的唯一的锁对象
    static Object o = new Object();
    //1.私有化本类的构造方法
    private MySingle2(){ }
    //2.创建的是本类对象的引用类型变量,用来保存对象的地址值,默认值是null
    private static MySingle2 single2 ;
    //3.提供公共的get方法
    synchronized public static MySingle2 getSingle2(){
        //4.判断之前是否创建过对象,之前创建过就直接走return
        //之前如果没有创建过,才走if,创建对象并将对象返回
        //6.有共享数据+多条语句操作数据,所以尽量提前处理,避免多线程数据安全隐患
        //6.1 解决方案1:加同步代码块
        //6.2 解决方案2:将本方法getSingle2()设置为同步方法
        //因为这个方法里所有的语句都需要同步
        synchronized (o) {//静态方法中使用的锁对象也得是静态的
            if (single2 == null) {//single2还是默认值,说明之前没有创建过对象
                single2 = new MySingle2();//没创建过才创建,并赋值给single2
            }
            return single2;
        }
    }
}

单例模式饿汉:

//0.创建自己的单例程序
class MySingle{
    //1.提供构造方法,并将构造方法私有化
    /*1.构造方法私有化的目的:为了防止外界随意创建本类对象*/
    private MySingle(){ }

    //2.创建本类对象,并将对象也私有化
    //4.2由于静态资源只能调用静态资源,所以single对象也需要设置成静态
    private static MySingle single = new MySingle();

    //3.提供公共的访问方式,返回创建好的对象
    //4.1为了不通过对象,直接调用本方法,需要将本方法设置为静态
    public static MySingle getSingle(){
        return single;
    }
}

二:工厂模式

工厂模式是Java中最常用的设计模式之一。这是类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。该模式用于封装和管理对象的创建

通过工厂模式,将创建产品实例的权利交给工厂,我们不再通过new来创建对象。降低了产品使用者和使用者直接的藕合关系。

Factory模式有3种变体:
(1)简单工厂模式: 允许接口创建对象,但不会暴露对象的创建逻辑。
(2)工厂方法模式:允许接口创建对象,但使用哪个类来创建对象,则是交由子类决定的。
(3)抽象工厂模式:抽象工厂是一个能够创建一系列相关的对象而无需指定/公开其具体类的接口。该模式能够提供其他工厂的对象,在其内部创建其他对象。
 

简单工厂模式:

单例模式-工厂模式_第1张图片

 使用手机生产讲解该模式:

//Phone类:手机标准规范类(AbstractProduct)

public interface Phone {
    void make(); 
}

//MiPhone类:制造小米手机(Product1)

public class MiPhone implements Phone {
    public MiPhone() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make xiaomi phone!");
    }
}

//IPhone类:制造苹果手机(Product2)

public class IPhone implements Phone {
    public IPhone() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make iphone!");
    }
}

//PhoneFactory类:手机代工厂(Factory)

public class PhoneFactory {
    public Phone makePhone(String phoneType) {
        if(phoneType.equalsIgnoreCase("MiPhone")){ //判断两字符串忽略大小写是否相等
            return new MiPhone();//如果存在则返回对应对象
        }
        else if(phoneType.equalsIgnoreCase("iPhone")) {
            return new IPhone();
        }
        return null;
    }
}

//演示:

public class Demo {
   public static void main(String[] arg) {
       PhoneFactory factory = new PhoneFactory();//创建工厂对象 通过工厂进行调用
       Phone miPhone = factory.makePhone("MiPhone");            // make xiaomi phone!
       IPhone iPhone = (IPhone)factory.makePhone("iPhone");    // make iphone!
   }
}



工厂方法模式:

和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂,也就是定义了一个抽象工厂,定义了产品的生产接口,但不是负责具体的产品,而是将生产任务交给不同的派生类工厂,这样不用通过指定类型来创建对象了。

单例模式-工厂模式_第2张图片

 其中和产品相关的Phone类、MiPhone类和IPhone类的定义不变:

//Phone类:手机标准规范类(AbstractProduct)

public interface Phone {
    void make(); 
}

//MiPhone类:制造小米手机(Product1)

public class MiPhone implements Phone {
    public MiPhone() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make xiaomi phone!");
    }
}

//IPhone类:制造苹果手机(Product2)

public class IPhone implements Phone {
    public IPhone() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make iphone!");
    }
}

//AbstractFactory类:生产不同产品的工厂的抽象类

public interface AbstractFactory { //定义了一个可以生产不同品牌手机的工厂
    Phone makePhone();
}

//XiaoMiFactory类:生产小米手机的工厂(ConcreteFactory1)

public class XiaoMiFactory implements AbstractFactory{
    @Override
    public Phone makePhone() {
        return new MiPhone();
    }
}

//AppleFactory类:生产苹果手机的工厂(ConcreteFactory2)

public class AppleFactory implements AbstractFactory {
    @Override
    public Phone makePhone() {  
        return new IPhone();
    }
}

//演示:

public class Demo {
    public static void main(String[] arg) {
        AbstractFactory miFactory = new XiaoMiFactory();
        AbstractFactory appleFactory = new AppleFactory();
        miFactory.makePhone();            // make xiaomi phone!
        appleFactory.makePhone();        // make iphone!
    }
}

 总结:

简单工厂和工厂方法模式的不同在于前者生成产生产品的行为封装在一个方法中,根据参数的类型进行实例化,同时不存在抽象接口。而后者则增加了抽象工厂,通过实现不同的工厂方法来创建不同的产品,一个方法通常对应一个产品,这种方式相较于前者扩展性更高,在需求增加时完全符合开闭原则和依赖倒置原则

抽象工厂模式: 

上面两种模式不管工厂怎么拆分抽象,都只是针对一类产品Phone(AbstractProduct),如果要生产另一种产品PC,应该怎么表示呢?

最简单的方式是把2中介绍的工厂方法模式完全复制一份,不过这次生产的是PC。但同时也就意味着我们要完全复制和修改Phone生产管理的所有代码,显然这是一个笨办法,并不利于扩展和维护。

抽象工厂模式通过在AbstarctFactory中增加创建产品的接口,并在具体子工厂中实现新加产品的创建,当然前提是子工厂支持生产该产品。否则继承的这个接口可以什么也不干
 

单例模式-工厂模式_第3张图片

 依旧通过手机案例演示:

//1.Phone类:手机标准规范类(AbstractProduct)-----

public interface Phone {
    void make(); 
}

//MiPhone类:制造小米手机(Product1)

public class MiPhone implements Phone {
    public MiPhone() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make xiaomi phone!");
    }
}

//IPhone类:制造苹果手机(Product2)

public class IPhone implements Phone {
    public IPhone() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make iphone!");
    }
}

//2.PC类:定义PC产品的接口(AbstractPC)-----

public interface PC {
    void make();
}

//MiPC类:定义小米电脑产品(MIPC)

public class MiPC implements PC {
    public MiPC() {
        this.make();
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make xiaomi PC!");
    }
}

//MAC类:定义苹果电脑产品(MAC)

public class MAC implements PC {  //都实现PC
    public MAC() {
        this.make();    
    }
    @Override
    public void make() {
        // TODO Auto-generated method stub
        System.out.println("make MAC!");
    }
}

//下面修改工厂相关的类的定义:
//3.AbstractFactory类:增加PC产品制造接口------

public interface AbstractFactory {
    Phone makePhone();
    PC makePC();
}

//XiaoMiFactory类:增加小米PC的制造(ConcreteFactory1)

public class XiaoMiFactory implements AbstractFactory{
    @Override
    public Phone makePhone() {
        return new MiPhone();
    }
    @Override
    public PC makePC() {
        return new MiPC();
    }
}


//AppleFactory类:增加苹果PC的制造(ConcreteFactory2)

public class AppleFactory implements AbstractFactory {
    @Override
    public Phone makePhone() {//通过接口定义多个产品让业务实现了新产品
        return new IPhone();
    }
    @Override
    public PC makePC() {
        return new MAC();
    }
}

//演示4.:
public class Demo {
    public static void main(String[] arg) {
        AbstractFactory miFactory = new XiaoMiFactory();
        AbstractFactory appleFactory = new AppleFactory();
        miFactory.makePhone();            // make xiaomi phone!
        miFactory.makePC();                // make xiaomi PC!
        appleFactory.makePhone();        // make iphone!
        appleFactory.makePC();            // make MAC!
    }
}

总结:

抽象工厂模式是工厂方法模式的升级版,后者面向单个产品,而前者面向的的是一个产品族。根据官方定义:为创建一组相关/互相依赖的对象提供一个接口而无需指定它们的具体类。
比如一个汽车工厂要生成骑车,而每种汽车都有车门、车轮胎等一系列产品,这意味着每增加一款汽车就需要增加一个新的工厂来提供新产品的实现。这时候就可以使用抽象工厂模式来进行设计。抽象工厂模式适用于一系列产品族。

你可能感兴趣的:(单例模式,java,抽象工厂模式)