одноэлементный шаблон
Проще говоря, в приложении есть только один экземпляр объекта определенного класса, и у вас нет возможности перейти к новому, потому что конструкторы модифицируются приватными, а их экземпляры обычно получаются через метод getInstance() .
Возвращаемое значение getInstance() является ссылкой на объект, а не на новый экземпляр, поэтому не путайте его с несколькими объектами. Режим singleton также очень прост в реализации, просто посмотрите демо
public class Singleton {
private static Singleton singleton;
private Singleton() {
}
public static Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
По привычке мне не терпится написать полноценные комментарии, боюсь вы не поймете, но этот код слишком простой, поэтому я не стал писать комментарии, если вы не понимаете эти строчки код, тогда можешь умыться и спать Ну, когда ты проснешься и вернешься в мой блог, может быть, ты сможешь это понять.
Вышеупомянутый является самым основным методом записи, также называемым методом ленивой записи (thread unsafe).Далее я объявлю несколько методов записи в одноэлементном режиме:
Написание в ленивом стиле (потокобезопасность)
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
Голодный китайский стиль
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
статический внутренний класс
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
перечислить
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
Этот метод пропагандируется автором Effective Java Джошем Блохом. Он может не только избежать проблем с многопоточной синхронизацией, но и предотвратить повторное создание новых объектов при десериализации. Можно сказать, что это очень сильный барьер. Однако я лично думаю, что из-за Единственное добавление функции перечисления, написание таким образом не может не чувствовать себя незнакомым.
замок с двойной проверкой
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
Резюме: лично я предпочитаю статический метод записи внутреннего класса и метод записи голодного китайского языка, на самом деле эти два метода записи могут справиться с большинством ситуаций. Другие способы письма также могут быть выбраны, в основном в зависимости от потребностей бизнеса.
Шаблон наблюдателя
Зависимости «один ко многим» между объектами: при изменении состояния объекта все зависящие от него объекты уведомляются и автоматически обновляются.
UML-диаграмма шаблона наблюдателя
Люди, которые не понимают картины, приходят сюда со скамейкой и дают вам каштан: Предположим, есть три человека: Сяомей (женщина, 28 лет), Лао Ван и Лао Ли. Сяомэй очень красив и кокетлив, Лао Ван и Лао Ли - два мужчины средних лет дяоси, всегда наблюдающие за каждым движением Сяомей. Однажды Сяомей сказала: «Моего мужа сегодня нет дома, он такой скучный один~~~, это предложение услышали Лао Ван и Лао Ли, и радость была разбита, и через некоторое время Лао Ван я бросилась к двери дома Сяомея, поэтому я вошел... Па ~ бах-бах-бах ~ Здесь Сяомей - наблюдатель, Лао Ван и Лао Ли - наблюдатели, Наблюдатель отправляет сообщение, а затем наблюдатели обрабатывают соответственно, см. код:
public interface Person {
//老王和老李通过这个接口可以接收到小美发过来的消息
void getMessage(String s);
}
Этот интерфейс эквивалентен телефонным номерам Лао Ван и Лао Ли. Когда Сяомей отправит уведомление, она вызовет getMessage. Звонок для вызова интерфейса. Неважно, если вы его не понимаете.
public class LaoWang implements Person {
private String name = "老王";
public LaoWang() {
}
@Override
public void getMessage(String s) {
System.out.println(name + "接到了小美打过来的电话,电话内容是:" + s);
}
}
public class LaoLi implements Person {
private String name = "老李";
public LaoLi() {
}
@Override
public void getMessage(String s) {
System.out.println(name + "接到了小美打过来的电话,电话内容是:->" + s);
}
}
Код очень простой, давайте посмотрим на код Xiaomei:
public class XiaoMei {
List<Person> list = new ArrayList<Person>();
public XiaoMei(){
}
public void addPerson(Person person){
list.add(person);
}
//遍历list,把自己的通知发送给所有暗恋自己的人
public void notifyPerson() {
for(Person person:list){
person.getMessage("今天家里就我一个人,你们过来吧,谁先过来谁就能得到我!");
}
}
}
Давайте напишем тестовый класс, чтобы увидеть, правильный ли результат
public class Test {
public static void main(String[] args) {
XiaoMei xiao_mei = new XiaoMei();
LaoWang lao_wang = new LaoWang();
LaoLi lao_li = new LaoLi();
//老王和老李在小美那里都注册了一下
xiao_mei.addPerson(lao_wang);
xiao_mei.addPerson(lao_li);
//小美向老王和老李发送通知
xiao_mei.notifyPerson();
}
}
Я сделал скриншот результата
результат операции
Идеально ~~~
шаблон декоратора
Существующая бизнес-логика дополнительно инкапсулируется для добавления дополнительных функций.Например, поток ввода-вывода в Java использует шаблон декоратора.При его использовании пользователи могут произвольно компоновать его для достижения желаемого эффекта. Возьмите каштан, я хочу съесть бутерброд, в первую очередь мне нужна большая колбаса, я люблю есть сливки, добавить немного сливок поверх колбасы, положить немного овощей, и, наконец, прослоить его двумя ломтиками хлеба , очень сытный обед, питательный и полезный. (ps: я не знаю, где в Шанхае продаются вкусные бутерброды, порекомендуйте, пожалуйста~) Так как же нам писать код? Во-первых, нам нужно написать класс Food, и пусть вся остальная еда наследует этот класс, см. код:
public class Food {
private String food_name;
public Food() {
}
public Food(String food_name) {
this.food_name = food_name;
}
public String make() {
return food_name;
};
}
Код очень простой, я не буду его объяснять, а затем мы напишем несколько подклассов, чтобы его наследовать:
//面包类
public class Bread extends Food {
private Food basic_food;
public Bread(Food basic_food) {
this.basic_food = basic_food;
}
public String make() {
return basic_food.make()+"+面包";
}
}
//奶油类
public class Cream extends Food {
private Food basic_food;
public Cream(Food basic_food) {
this.basic_food = basic_food;
}
public String make() {
return basic_food.make()+"+奶油";
}
}
//蔬菜类
public class Vegetable extends Food {
private Food basic_food;
public Vegetable(Food basic_food) {
this.basic_food = basic_food;
}
public String make() {
return basic_food.make()+"+蔬菜";
}
}
Эти классы почти одинаковые.Конструктор передает параметр типа Food, а затем добавляет свою логику в метод make.Если вы до сих пор не понимаете, почему так написали, не волнуйтесь, берите посмотрите на мой тестовый класс Как это написано, вы поймете, когда увидите это
public class Test {
public static void main(String[] args) {
Food food = new Bread(new Vegetable(new Cream(new Food("香肠"))));
System.out.println(food.make());
}
}
Если видите, то она упакована слой за слоем.Давайте посмотрим изнутри:я добавила новую колбасу на самую внутреннюю сторону,снаружи на колбасу намотала слой крема,снаружи добавила слой овощей сливки, и добавил слой овощей на внешней стороне Хлеб размещен, не правда ли, очень ярко, ха-ха~ Этот шаблон дизайна точно такой же, как и в реальной жизни, понимаете? Посмотрим на результаты
результат операции
бутерброд готов
режим адаптера
Соединение двух совершенно разных вещей вместе похоже на реальный трансформер. Предположим, что напряжение, требуемое зарядным устройством для мобильного телефона, составляет 20 В, но нормальное напряжение составляет 220 В. В это время необходим трансформатор для преобразования напряжения 220 В в напряжение 20 В. Таким образом, трансформатор подключает напряжение 20 В к мобильному телефону. .
public class Test {
public static void main(String[] args) {
Phone phone = new Phone();
VoltageAdapter adapter = new VoltageAdapter();
phone.setAdapter(adapter);
phone.charge();
}
}
// 手机类
class Phone {
public static final int V = 220;// 正常电压220v,是一个常量
private VoltageAdapter adapter;
// 充电
public void charge() {
adapter.changeVoltage();
}
public void setAdapter(VoltageAdapter adapter) {
this.adapter = adapter;
}
}
// 变压器
class VoltageAdapter {
// 改变电压的功能
public void changeVoltage() {
System.out.println("正在充电...");
System.out.println("原始电压:" + Phone.V + "V");
System.out.println("经过变压器转换之后的电压:" + (Phone.V - 200) + "V");
}
}
Заводская выкройка
Простой фабричный шаблон: абстрактный интерфейс, классы реализации нескольких абстрактных интерфейсов и фабричный класс для создания экземпляров абстрактных интерфейсов.
// 抽象产品类
abstract class Car {
public void run();
public void stop();
}
// 具体实现类
class Benz implements Car {
public void run() {
System.out.println("Benz开始启动了。。。。。");
}
public void stop() {
System.out.println("Benz停车了。。。。。");
}
}
class Ford implements Car {
public void run() {
System.out.println("Ford开始启动了。。。");
}
public void stop() {
System.out.println("Ford停车了。。。。");
}
}
// 工厂类
class Factory {
public static Car getCarInstance(String type) {
Car c = null;
if ("Benz".equals(type)) {
c = new Benz();
}
if ("Ford".equals(type)) {
c = new Ford();
}
return c;
}
}
public class Test {
public static void main(String[] args) {
Car c = Factory.getCarInstance("Benz");
if (c != null) {
c.run();
c.stop();
} else {
System.out.println("造不了这种汽车。。。");
}
}
}
Шаблон фабричного метода: существует четыре роли: абстрактный фабричный шаблон, конкретный фабричный шаблон, абстрактный шаблон продукта, шаблон конкретного продукта. Это больше не фабричный класс для создания экземпляра конкретного продукта, а подкласс абстрактной фабрики для создания экземпляра продукта.
// 抽象产品角色
public interface Moveable {
void run();
}
// 具体产品角色
public class Plane implements Moveable {
@Override
public void run() {
System.out.println("plane....");
}
}
public class Broom implements Moveable {
@Override
public void run() {
System.out.println("broom.....");
}
}
// 抽象工厂
public abstract class VehicleFactory {
abstract Moveable create();
}
// 具体工厂
public class PlaneFactory extends VehicleFactory {
public Moveable create() {
return new Plane();
}
}
public class BroomFactory extends VehicleFactory {
public Moveable create() {
return new Broom();
}
}
// 测试类
public class Test {
public static void main(String[] args) {
VehicleFactory factory = new BroomFactory();
Moveable m = factory.create();
m.run();
}
}
Шаблон абстрактной фабрики: в отличие от шаблона фабричного метода, фабрика в шаблоне фабричного метода производит только один продукт, в то время как фабрика в шаблоне абстрактной фабрики производит несколько продуктов.
/抽象工厂类
public abstract class AbstractFactory {
public abstract Vehicle createVehicle();
public abstract Weapon createWeapon();
public abstract Food createFood();
}
//具体工厂类,其中Food,Vehicle,Weapon是抽象类,
public class DefaultFactory extends AbstractFactory{
@Override
public Food createFood() {
return new Apple();
}
@Override
public Vehicle createVehicle() {
return new Car();
}
@Override
public Weapon createWeapon() {
return new AK47();
}
}
//测试类
public class Test {
public static void main(String[] args) {
AbstractFactory f = new DefaultFactory();
Vehicle v = f.createVehicle();
v.run();
Weapon w = f.createWeapon();
w.shoot();
Food a = f.createFood();
a.printName();
}
}
Прокси-режим (прокси)
Есть два вида: статический прокси и динамический прокси. Давайте сначала поговорим о статических прокси, я не буду говорить о многих теоретических вещах, даже если я буду говорить об этом, вы этого не поймете. Какие настоящие роли, абстрактные роли, прокси-роли, делегированные роли. . . Запутался, не могу понять. Когда я раньше изучал модель агентства, я посмотрел ее в Интернете, там много информации, откройте ссылку, чтобы увидеть, в основном это даст вам анализ того, какая роль, есть много теорий, кажется, очень трудоемко, если не верите, можете пойти и посмотреть. Слушайте, я просто не понимаю, что они говорят. Давайте не будем фантазировать и говорить прямо с примерами из жизни. (Примечание: я не отрицаю здесь теоретические знания, я просто думаю, что иногда теоретические знания неясны и трудны для понимания, и те, кто любит придираться к стороне, уходят, вы здесь, чтобы изучать знания, а не придираться)
Когда мы достигнем определенного возраста, мы поженимся, а жениться — дело очень хлопотное (в том числе и тем, кого к женитьбе побуждают родители). Состоятельные семьи могут найти церемониймейстера на свадьбе, которая выглядит живо и иностранно.Теперь дело свадебной компании здесь.Нам нужно только дать деньги,а свадебная компания поможет нам организовать весь комплекс брачные процедуры. Весь процесс, вероятно, таков: семья настаивает на свадьбе -> семья соглашается пожениться в тот же день -> найти надежную свадебную компанию -> провести свадебную церемонию в оговоренное время -> брак заключен.
Мы понятия не имеем, как свадебная компания планирует организовать свадебную программу и что свадебная компания будет делать после свадьбы. . . Не волнуйтесь, это не черный посредник, пока мы даем деньги другим, они будут делать для нас хорошо. Поэтому свадебная компания здесь эквивалентна роли агентства, теперь вы понимаете, что такое роль агентства.
Пожалуйста, посмотрите реализацию кода:
//代理接口
public interface ProxyInterface {
//需要代理的是结婚这件事,如果还有其他事情需要代理,比如吃饭睡觉上厕所,也可以写
void marry();
//代理吃饭(自己的饭,让别人吃去吧)
//void eat();
//代理拉屎,自己的屎,让别人拉去吧
//void shit();
}
В цивилизованном обществе я не буду писать о том, чтобы действовать агентом пожрать, а агентом покакать.Это оскорбительно для общества.Полезно понимать.
Что ж, смотрим свадебную фирму:
public class WeddingCompany implements ProxyInterface {
private ProxyInterface proxyInterface;
public WeddingCompany(ProxyInterface proxyInterface) {
this.proxyInterface = proxyInterface;
}
@Override
public void marry() {
System.out.println("我们是婚庆公司的");
System.out.println("我们在做结婚前的准备工作");
System.out.println("节目彩排...");
System.out.println("礼物购买...");
System.out.println("工作人员分工...");
System.out.println("可以开始结婚了");
proxyInterface.marry();
System.out.println("结婚完毕,我们需要做后续处理,你们可以回家了,其余的事情我们公司来做");
}
}
Видя нет, свадебной компании нужно сделать много дел, давайте посмотрим на кодекс брачной семьи:
public class NormalHome implements ProxyInterface{
@Override
public void marry() {
System.out.println("我们结婚啦~");
}
}
Это уже очевидно. Супружеской семье нужно только пожениться, а свадебная компания должна позаботиться обо всем. Свадебная компания делает все до и после. Я слышал, что свадебная компания сейчас очень прибыльна. В этом причина. Дон не зарабатываешь?
Давайте посмотрим на код тестового класса:
public class Test {
public static void main(String[] args) {
ProxyInterface proxyInterface = new WeddingCompany(new NormalHome());
proxyInterface.marry();
}
}
Результаты приведены ниже:
Как мы и ожидали, результат правильный.Это статический прокси.Я не хочу говорить о динамическом прокси.Он как-то связан с javareflection.В интернете много информации.Буду обновлять позже, когда у меня будет время.
Если вы считаете, что то, что я написал, полезно для вас, ставьте палец вверх и поддержите меня!
У меня есть общедоступная учетная запись WeChat, и я часто делюсь галантерейными товарами, связанными с технологией Java; если вам нравится мой обмен, вы можете использовать WeChat для поиска «Java Head» или «javatuanzhang», чтобы подписаться.