了解Spring中常见的设计模式-------------------工厂模式

常见的设计模式:

工厂模式、单例模式、原型模式、代理模式、策略模式、委派模式、适配器模式、装饰器模式、观察者模式

SpringIOC:工厂模式、单例模式、装饰器模式

SpringAOP:代理模式,观察者模式

SpringMVC:委派模式,适配器模式

SpringJDBC:模版方法

1、工厂模式

1.1简单工厂模式:

适用于:创建的对象较少,客户端只关心传入工厂类的参数,对于如何创建对象的逻辑并不关心。

优点:只需要传入正确的参数,就可以获取所需的对象,对于创建的细节无需关心。

缺点:工厂类的职责过于重,当需要创建新的对象(产品),就需要修改工厂的判断逻辑,违背开闭原则;不易于扩展复杂的产品结构。

public interface Fruit {
    void price();
}

@Data
public class Apple implements Fruit {
    private String name;
    private float weight;
    private BigDecimal price;

    public Apple() {
    }

    public Apple(String name) {
        this.name = name;
    }

    @Override
    public void price() {

    }
}


public class FruitStore {

    public Apple getFruit(String name) {
        if (name.equals("apple")) {
            return new Apple(name);
        } else {
            return null;
        }
    }

    public Fruit createFruit(String className) {
        try {
            if (className != null && className.length() > 0) {
                Class classforName = Class.forName(className);
                System.out.println("classforName---" + classforName);
                Object object = classforName.newInstance();
                return (Apple)object;
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Fruit createFruit(Class className) {
        try {
            if (className != null) {
                return (Apple)className.newInstance();
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}


public class SimpleFactoryTest {
    public static void main(String[] args) {
        FruitStore fruitStore = new FruitStore();
        Fruit fruit = fruitStore.getFruit("apple");
        System.out.println(fruit.toString());
        Fruit fruit1 = fruitStore.createFruit("com.tealala.pattern.factoryModel.simpleFactory.Apple");
        System.out.println(fruit1.toString());
        Fruit fruit2 = fruitStore.createFruit(Apple.class);
        System.out.println(fruit2.toString());

    }
}


测试结果为:
Apple(name=apple, weight=0.0, price=null)
classforName---class com.tealala.pattern.factory.Apple
Apple(name=null, weight=0.0, price=null)
Apple(name=null, weight=0.0, price=null)

1.2工厂方法模式(Factory Method Pattern)

适用场景:创建对象需要大量重复代码,客户端(应用层)不需要依赖产品实例如何创建,实现等细节。一个类通过子类来指定创建哪个类。

定义一个创建对象的接口,决定实例化哪个类由实现这个接口的子类来决定,具体来说就是:工厂接口的类实例化由子类来具体实现。【Define a interface for creating an Object,but let subclass decide which class to instantiate .The Factory lets a subclass defer instantiation it uses to subclass】

优点:只需要关心所需要产品对应的工厂,无需关心工厂具体实现的细节;加入新的产品符合开闭原则,提高的系统的可扩展性。

缺点:类的个数容易过多,增加代码结构的复杂度,增加系统的抽象性和理解难度。

@Data
public class Banana implements Fruit {
    private String name;

    public Banana() {
    }

    public Banana(String name) {
        this.name = name;
    }

    @Override
    public void price() {

    }
}



public interface FruitStore {
    Fruit init();
}



public class AppleStore implements FruitStore{
    @Override
    public Fruit init() {
        return new Apple("apple");
    }
}



public class BananaStore implements FruitStore {
    @Override
    public Fruit init() {
        return new Banana("banana");
    }
}



public class MethodFactoryTest {
    public static void main(String[] args) {
        FruitStore bananaStore = new BananaStore();
        Fruit banana = bananaStore.init();
        FruitStore appleStore = new AppleStore();
        Fruit apple = appleStore.init();
        System.out.println(banana.toString());
        System.out.println(apple.toString());
    }
}


运行结果:
Banana(name=banana)
Apple(name=apple, weight=0.0, price=null)

1.3抽象工厂模式(Abstract Factory Pattern):

提供一个创建一系列相关的或相互依赖对象的接口,无需指定它们的具体类【Provide an interface for creating families of related or dependent object without specifying their concrete classes】

属于创建型模型

适用场景:客户端(应用层)不依赖于产品类实例如何被创建,实现等细节;强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码;提供一个产品类的库,所有的产品以同一个接口出现,从而使客户端不依赖于具体的实现。

优点:产品在应用层隔离,无需关心创建细节;将一个系列的产品族统一到一起创建。

缺点:提前规定了所有可能被创建的产品集合,产品族中要扩展产品比较困难,需要修改抽象工厂的接口;增加了系统的抽象性和理解难度。

public interface Fruit {
    String getName();
}

public interface IApple extends Fruit{
}

public interface IBanana extends Fruit {
}

public class CDApple implements IApple {
    @Override
    public String getName() {
        return "cdApple";
    }
}

public class CQApple implements IApple {
    @Override
    public String getName() {
        return "cqApple";
    }
}

public class CDBanana implements IBanana{
    @Override
    public String getName() {
        return "cdBanana";
    }
}

public class CQBanana implements IBanana {
    @Override
    public String getName() {
        return "cqBanana";
    }
}

public interface FruitStoreFactory {

    IApple initApple();

    IBanana initBanana();
}

public class CDStoreFactory implements FruitStoreFactory {

    @Override
    public IApple initApple() {
        return new CDApple();
    }

    @Override
    public IBanana initBanana() {
        return new CDBanana();
    }
}

public class CQStoreFactory implements FruitStoreFactory {
    @Override
    public IApple initApple() {
        return new CQApple();
    }

    @Override
    public IBanana initBanana() {
        return new CQBanana();
    }
}


public class AbstracFactoryTest {

    public static void main(String[] args) {
        FruitStoreFactory fruitStoreFactory1 = new CDStoreFactory();
        IApple apple1 = fruitStoreFactory1.initApple();
        IBanana banana1 = fruitStoreFactory1.initBanana();
        System.out.println(apple1.getName());
        System.out.println(banana1.getName());
        FruitStoreFactory fruitStoreFactory2 = new CQStoreFactory();
        IApple apple2 = fruitStoreFactory2.initApple();
        IBanana banana2 = fruitStoreFactory2.initBanana();
        System.out.println(apple2.getName());
        System.out.println(banana2.getName());
    }
}


执行结果为:
cdApple
cdBanana
cqApple
cqBanana
发布了35 篇原创文章 · 获赞 0 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/tealala/article/details/103416753
今日推荐