一、简单工厂
/**
* 简单工厂中,所有产品必须拥有相同接口或父类,属于同一产品系列的
* 1. 定义商品接口
* 2. 具体商品继承商品接口,实现接口定义的方法
* 3. 定义工厂,有个静态static的获取实例的方法getProduct(String p)
* 直接通过工厂名.getProduct("p")来获取具体对象
*
* 缺点: 不符合开闭原则
* getProduct()方法中需要定义每个商品,增加商品的话这里需要自己手动添加if(){}
* 商品子类过多会太庞大,不适于维护
*/
public class SimpleFactory {
public static void main(String[] args) {
//不需要创建产品,直接从工厂中获取要哪个产品就好了
//不合理: 要将创建产品方法设为static
// Factory factory = new Factory();
// Product p = factory.getProduct("p2");
//静态方法后:
Product p = Factory.getProduct("p1");
p.operation1();
p.operation2();
}
}
//创建工厂
class Factory{
//设静态 更方便
public static Product getProduct(String productType){
Product product = null;
if("p1".equals(productType)){
product = new Product1();
}else if("p2".equals(productType)){
product = new Product2();
}else {
product = new ProductX();
}
return product;
}
}
//具体产品
class Product1 implements Product{
@Override
public void operation1() {
System.out.println("产品1,操作1");
}
@Override
public void operation2() {
System.out.println("产品1,操作2");
}
}
class Product2 implements Product{
@Override
public void operation1() {
System.out.println("产品2,操作1");
}
@Override
public void operation2() {
System.out.println("产品2,操作2");
}
}
class ProductX implements Product{
@Override
public void operation1() {
System.out.println("产品X,操作1");
}
@Override
public void operation2() {
System.out.println("产品X,操作2");
}
}
//产品接口
interface Product{
public void operation1();
public void operation2();
}
二、工厂方法
优点:
- 客户端不负责对象的创建,而是由专门的工厂类完成
- 客户端只负责对象的调用,实现了创建和调用的分离
- 增加或减少产品子类的时候,不用去修改工厂类,而是对应增加或删除产品工厂子类
- 符合开闭原则,即使产品子类过多,也不会导致工厂类庞大,利于后期维护
产品类
public abstract class Calculator {
protected int num1;
protected int num2;
public abstract int cal();
//...下面还有构造方法、get set
}
具体产品子类
public class AddCalculator extends Calculator {
@Override
public int cal() {
return num1+num2;
}
}
class SubCalculator extends Calculator {
@Override
public int cal() {
return num1-num2;
}
}
class DivCalculator extends Calculator {
@Override
public int cal() {
return num1/num2;
}
}
class MulCalculator extends Calculator {
@Override
public int cal() {
return num1*num2;
}
}
工厂接口
public interface CalFactory {
public Calculator getCal();
}
具体产品工厂
class AddFactory implements CalFactory{
@Override
public Calculator getCal() {
return new AddCalculator();
}
}
class SubFactory implements CalFactory{
@Override
public Calculator getCal() {
return new SubCalculator();
}
}
class MulFactory implements CalFactory{
@Override
public Calculator getCal() {
return new MulCalculator();
}
}
class DivFactory implements CalFactory{
@Override
public Calculator getCal() {
return new DivCalculator();
}
}
三、单例模式
1. 饿汉式
public class Hungry {
private static Hungry instance = new Hungry();
//单例模式构造方法要私有 这样别人就不能new创建这个对象了
private Hungry() {}
public static Hungry getInstance(){
return instance;
}
}
2. 懒汉式(不安全)
public class LazyMan {
private static LazyMan instance;
//禁止类外部直接new
private LazyMan() {
}
public static LazyMan getInstance(){
if (instance==null){
instance = new LazyMan();
}
return instance;
}
}
3. 懒汉式(线程安全 synchronized)
public class LazyManSafe {
private static LazyManSafe instance;
//禁止类外部直接new
private LazyManSafe() {
}
//加了synchronized :影响效率 所以用DCL双重检验
public static synchronized LazyManSafe getInstance(){
if(instance==null){
instance = new LazyManSafe();
}
return instance;
}
}
4. 双重检验锁(DCL)
//双重检验锁DCL 也是懒汉的一种
public class DoubleChecked_Locking {
//volatile: 保证多线程下instance在多个线程之间的可见性和禁止指令重排
private volatile static DoubleChecked_Locking instance;
private DoubleChecked_Locking(){}
public static DoubleChecked_Locking getInstance(){
if(instance==null){ //提高效率 不用每次都上锁↓
synchronized (DoubleChecked_Locking.class){
if (instance==null){ //有必要
instance = new DoubleChecked_Locking();
}
}
}
return instance;
}
}
5. 静态内部类
//静态内部类方式
public class InnerClass {
private static class InnerClassHolder{
private static final InnerClass INSTANCE = new InnerClass();
}
private InnerClass(){}
public static final InnerClass getInstance(){
return InnerClassHolder.INSTANCE;
}
}