представлять
- Предположим, есть водитель, которому нужно ехать в определенный город, поэтому мы даем ему машину
public class Demo {
public static void main(String[] args) {
Car car = new Car();
car.run();
}
}
public class Car {
public void run(){
System.out.println("汽车正在向前跑...");
}
}
- Что, если мы хотим всегда давать этому водителю машину? (Синглтон)
- Во-первых, мы не можем пропустить водителя одного
new
производит автомобиль, но вместо этого следует вызвать, позвонивCar
Метод в классе предоставляет автомобиль внешнему миру.
public class Car {
private static Car car = new Car();//用于提供给外界, 始终是同一辆车
private Car(){};//私有构造方法, 在类之外不能通过new获得本类对象了, 保证了单例
public Car getInstance(){
return car;
}
public void run(){
System.out.println("汽车正在向前跑...");
}
}
public static void main(String[] args) {
Car car = Car.getInstance();
car.run();
}
простая фабрика
- Рассмотрим следующее: если мы не хотим иметь только транспортное средство как транспортное средство, мы хотим настроить транспортное средство и настроить процесс производства транспортного средства, что нам делать?
- Полиморфизм должен прийти на ум, как только возникнет концепция от автомобиля к транспортному средству.
Moveable
интерфейс, объявленный в интерфейсеrun()
метод, все классы транспортных средств реализуют этот интерфейс. - Для индивидуального производственного процесса мы можем произвести соответствующий автомобиль на заводе.
public interface Moveable {
void run();
}
public class Car implements Moveable{
public Car(){};//私有构造方法, 在类之外不能通过new获得本类对象了, 保证了单例
public void run(){
System.out.println("汽车正在向前跑...");
}
}
public abstract class VehicleFactory {
public abstract Moveable create();
}
public class CarFactory extends VehicleFactory {
@Override
public Moveable create() {
return new Car();
}
}
//Test
public static void main(String[] args) {
VehicleFactory factory = new CarFactory();
Moveable m = factory.create();
m.run();
}
абстрактная фабрика
- Давайте выкинем из головы картину простой фабрики и опишем другую реализацию фабрики.
- Предположим, что водитель в начале не обычный водитель, ему нужен не только транспорт, чтобы добраться до определенного города, но и AK47, а также яблоко для непредвиденных нужд в дороге.
- Поэтому нам нужно дать ему фабрику по производству этой серии продуктов.
- Чтобы улучшить масштабируемость, мы также надеемся, что разные фабрики смогут производить разные серии продуктов, например, вышеупомянутая фабрика A производит автомобили, AK47 и яблоки, а фабрика B производит самолеты, ракетные установки и булочки Wangzai.
//test
public static void main(String[] args) {
AbstractFactory factory = new Factory1();
Vehiche v = factory.createVehiche();
Weapon w = factory.createWeapon();
Food f = factory.createFood();
v.run();
w.fire();
f.eat();
}
public abstract class Vehiche {//交通工具的抽象类
public abstract void run();
}
public abstract class Weapon {//武器的抽象类
public abstract void fire();
}
public abstract class Food {//食物的抽象类
public abstract void eat();
}
public class Car extends Vehiche{一种具体的交通工具
@Override
public void run() {
System.out.println("小汽车启动...");
}
}
public class AK47 extends Weapon {//一种具体的武器
@Override
public void fire() {
System.out.println("哒哒哒...");
}
}
public class Apple extends Food{//一种具体的食物
@Override
public void eat() {
System.out.println("大口吃苹果...");
}
}
//抽象工厂
public abstract class AbstractFactory {
public abstract Vehiche createVehiche();
public abstract Weapon createWeapon();
public abstract Food createFood();
}
//抽象工厂的实现1
public class Factory1 extends AbstractFactory {
@Override
public Vehiche createVehiche() {
return new Car();
}
@Override
public Weapon createWeapon() {
return new AK47();
}
@Override
public Food createFood() {
return new Apple();
}
}
- Подводя итог, каковы плюсы и минусы абстрактных фабрик и простых фабрик?
- Абстрактная фабрика может производить серию продуктов и может легко заменить серию продуктов, но если вы хотите добавить еще одну разновидность в серию продуктов, это будет очень хлопотно.Например, добавление серии продуктов выше
盔甲
Абстрактный класс, то абстрактная фабрика и соответствующая реализация должны модифицировать исходный код. - Простая фабрика может гибко производить одну разновидность продукции, но если разновидностей много, возникнет проблема затопления фабрики.
- Преимущества и недостатки этих двух дополняют друг друга, поэтому существует ли фабричная реализация, которая может быть совместима с преимуществами этих двух?
spring
Заводская реализация , дающая решение.
Весенний бобовый завод
- Снова рассмотрим самый примитивный случай, есть
Moveable
интерфейс, который имеетrun
метод,Car
Класс car реализует этот интерфейс.
public static void main(String[] args) {
Moveable m = new Car();
m.run();
}
public interface Moveable {
void run();
}
public class Car implements Moveable{
@Override
public void run() {
System.out.println("小汽车往前跑...");
}
}
- В bean factory Spring новые объекты не передаются
new
Ключевое слово получается, но получается через конфигурационный файл. - Конкретный процесс: сначала прочитайте файл конфигурации, чтобы получить класс
class
объект, а затем передатьclass
Объекты создают конкретные экземпляры объектов.
public static void main(String[] args) throws Exception {
//获取配置文件
Properties props = new Properties();
props.load(Test.class.getClassLoader().getResourceAsStream("spring.properties"));
//获取配置文件中配置的类
String vehicheTypeName = props.getProperty("vehicheTypeName");
//反射生成对应的对象
Moveable m = (Moveable) Class.forName(vehicheTypeName).newInstance();
m.run();
}
//spring.properties
vehicheTypeName=designPattern.factory.springFactory.Car
- выше правильно
spring
Макет, используемый на фабрике бобов, ниже мы используем настоящийspring
генерироватьCar
возразите и сравните.
public static void main(String[] args) throws Exception {
BeanFactory bf = new ClassPathXmlApplicationContext("applicationContext.xml");
Vehiche v = (Vehiche)bf.getBean("v");
v.run();
}
//配置文件
<bean id="v" class="designPattern.factory.Car">
</bean>
- После сравнения мы обнаружили, что между простой фабрикой, которую мы написали, и бобовой фабрикой весны нет никакой разницы в использовании.
spring
Он настолько прост в использовании, что давайте смоделируем реализацию фабрики bean-компонентов Spring.
Реализация фабрики Mock Spring
Аналоговый IOC
- сказать
spring
Являетсяbean
контейнер, следующий код покажет, как он генерируетсяbean
, и положиbean
Поместите в контейнер для пользователя, чтобы получить. - Идея относительно проста:
- Создайте
BeanFactory
Заводской интерфейс, добавление методовgetBean()
. - Создайте
BeanFactory
класс реализацииClassPathXmlApplicationContext
Конкретная реализация IOC будет показана в этом классе реализации. -
ClassPathXmlApplicationContext
нужен одинcontainer
Контейнер хранит созданный объект bean, который используется здесьHashMap
выполнить. - существует
ClassPathXmlApplicationContext
читать в конструктореspring
Файл конфигурации, используемый здесьdom4j
, После прочтения конфигурационного файла согласноbean
изclass
Свойства создаются с использованием отраженияbean
объект, затем поместитеid
а такжеbean
объект какkey
а такжеvalue
добавил в контейнер. - когда фабрика называется
getBean()
метод, найдите соответствующий из контейнераbean
и вернуться.
public static void main(String[] args) throws Exception {
BeanFactory bf = new ClassPathXmlApplicationContext("applicationContext.xml");
Vehiche v = (Vehiche) bf.getBean("v");
v.run();
}
//BeanFactory的实现类
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String, Object> container = new HashMap<>();//用于存放bean对象的容器
//在构造方法中读取xml配置文件, 把bean对象都创建好并放入容器中
public ClassPathXmlApplicationContext(String propAddr) throws Exception {
SAXReader reader = new SAXReader();
File file = new File(this.getClass().getClassLoader().getResource(propAddr).toURI());
Document document = reader.read(file);
Element root = document.getRootElement();
List<Element> childElements = root.elements();
for (Element child : childElements) {
Object bean = Class.forName(child.attributeValue("class")).newInstance();
container.put(child.attributeValue("id"), bean);
}
}
@Override
public Object getBean(String beanId) {
return container.containsKey(beanId) ? container.get(beanId) : null;
}
}
//极简BeanFactory
public interface BeanFactory {
Object getBean(String beanId);
}
//xml中配置的bean
<bean id="v" class="designPattern.factory.Car">
</bean>