{"id":356,"date":"2018-05-08T14:13:40","date_gmt":"2018-05-08T02:13:40","guid":{"rendered":"https:\/\/content.ronella.xyz\/apps\/wordpress\/?p=356"},"modified":"2023-10-05T21:57:04","modified_gmt":"2023-10-05T08:57:04","slug":"behavioral-design-patterns","status":"publish","type":"post","link":"https:\/\/www.ronella.xyz\/?p=356","title":{"rendered":"Behavioral Design Patterns"},"content":{"rendered":"<p>Behavioral design patterns focus on how <strong>objects and classes interact and communicate with each other<\/strong>. They deal with the responsibilities of objects and the delegation of tasks among them. These patterns help you define clear and efficient ways for objects to collaborate while keeping your codebase flexible and maintainable.<\/p>\n<h2>Chain of Responsibility Pattern<\/h2>\n<p>The Chain of Responsibility Pattern passes a request along a chain of handlers. Each handler decides either to process the request or to pass it to the next handler in the chain.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">\/\/ Handler interface\nabstract class Handler {\n    protected Handler successor;\n\n    public void setSuccessor(Handler successor) {\n        this.successor = successor;\n    }\n\n    public abstract void handleRequest(Request request);\n}\n\n\/\/ Request class\nclass Request {\n    private String requestType;\n    private String requestDescription;\n\n    public Request(String requestType, String requestDescription) {\n        this.requestType = requestType;\n        this.requestDescription = requestDescription;\n    }\n\n    public String getRequestType() {\n        return requestType;\n    }\n\n    public String getRequestDescription() {\n        return requestDescription;\n    }\n}\n\n\/\/ Concrete Handlers\nclass Clerk extends Handler {\n    @Override\n    public void handleRequest(Request request) {\n        if (request.getRequestType().equalsIgnoreCase(&quot;Leave&quot;)) {\n            System.out.println(&quot;Clerk: Approving leave request - &quot; + request.getRequestDescription());\n        } else if (successor != null) {\n            successor.handleRequest(request);\n        }\n    }\n}\n\nclass Supervisor extends Handler {\n    @Override\n    public void handleRequest(Request request) {\n        if (request.getRequestType().equalsIgnoreCase(&quot;Purchase&quot;)) {\n            System.out.println(&quot;Supervisor: Approving purchase request - &quot; + request.getRequestDescription());\n        } else if (successor != null) {\n            successor.handleRequest(request);\n        }\n    }\n}\n\nclass Manager extends Handler {\n    @Override\n    public void handleRequest(Request request) {\n        if (request.getRequestType().equalsIgnoreCase(&quot;Raise Salary&quot;)) {\n            System.out.println(&quot;Manager: Approving salary raise request - &quot; + request.getRequestDescription());\n        } else {\n            System.out.println(&quot;Manager: Cannot handle this request.&quot;);\n        }\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Handler clerk = new Clerk();\n        Handler supervisor = new Supervisor();\n        Handler manager = new Manager();\n\n        clerk.setSuccessor(supervisor);\n        supervisor.setSuccessor(manager);\n\n        Request request1 = new Request(&quot;Leave&quot;, &quot;2 days leave&quot;);\n        Request request2 = new Request(&quot;Purchase&quot;, &quot;Office supplies&quot;);\n        Request request3 = new Request(&quot;Raise Salary&quot;, &quot;Employee X&quot;);\n\n        clerk.handleRequest(request1);\n        clerk.handleRequest(request2);\n        clerk.handleRequest(request3);\n    }\n}<\/code><\/pre>\n<h2>Command Pattern<\/h2>\n<p>The Command Pattern encapsulates a request as an object, thereby allowing you to parameterize clients with queues, requests, and operations. It also enables undoable operations and transactional behavior.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">\/\/ Receiver\nclass Light {\n    void turnOn() {\n        System.out.println(&quot;Light is on&quot;);\n    }\n\n    void turnOff() {\n        System.out.println(&quot;Light is off&quot;);\n    }\n}\n\n\/\/ Command interface\ninterface Command {\n    void execute();\n}\n\n\/\/ Concrete Commands\nclass TurnOnLightCommand implements Command {\n    private Light light;\n\n    public TurnOnLightCommand(Light light) {\n        this.light = light;\n    }\n\n    @Override\n    public void execute() {\n        light.turnOn();\n    }\n}\n\nclass TurnOffLightCommand implements Command {\n    private Light light;\n\n    public TurnOffLightCommand(Light light) {\n        this.light = light;\n    }\n\n    @Override\n    public void execute() {\n        light.turnOff();\n    }\n}\n\n\/\/ Invoker\nclass RemoteControl {\n    private Command command;\n\n    public void setCommand(Command command) {\n        this.command = command;\n    }\n\n    public void pressButton() {\n        command.execute();\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Light livingRoomLight = new Light();\n        Command turnOnCommand = new TurnOnLightCommand(livingRoomLight);\n        Command turnOffCommand = new TurnOffLightCommand(livingRoomLight);\n\n        RemoteControl remoteControl = new RemoteControl();\n\n        remoteControl.setCommand(turnOnCommand);\n        remoteControl.pressButton();\n\n        remoteControl.setCommand(turnOffCommand);\n        remoteControl.pressButton();\n    }\n}<\/code><\/pre>\n<h2>Interpreter Pattern<\/h2>\n<p>The Interpreter Pattern is used to define a grammar for interpreting a language and provides a way to evaluate expressions in the language.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">\/\/ Context\nclass Context {\n    private String input;\n    private int output;\n\n    public Context(String input) {\n        this.input = input;\n    }\n\n    public String getInput() {\n        return input;\n    }\n\n    public void setOutput(int output) {\n        this.output = output;\n    }\n\n    public int getOutput() {\n        return output;\n    }\n}\n\n\/\/ Abstract Expression\ninterface Expression {\n    void interpret(Context context);\n}\n\n\/\/ Terminal Expression\nclass NumberExpression implements Expression {\n    private int number;\n\n    public NumberExpression(int number) {\n        this.number = number;\n    }\n\n    @Override\n    public void interpret(Context context) {\n        context.setOutput(number);\n    }\n}\n\n\/\/ Non-terminal Expression\nclass AddExpression implements Expression {\n    private Expression left;\n    private Expression right;\n\n    public AddExpression(Expression left, Expression right) {\n        this.left = left;\n        this.right = right;\n    }\n\n    @Override\n    public void interpret(Context context) {\n        left.interpret(context);\n        int leftValue = context.getOutput();\n        right.interpret(context);\n        int rightValue = context.getOutput();\n        context.setOutput(leftValue + rightValue);\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        \/\/ Example: 1 + 2\n        Context context = new Context(&quot;1 + 2&quot;);\n        Expression expression = parseExpression(context.getInput());\n        expression.interpret(context);\n        System.out.println(&quot;Result: &quot; + context.getOutput());\n    }\n\n    private static Expression parseExpression(String input) {\n        String[] tokens = input.split(&quot; &quot;);\n        Expression left = new NumberExpression(Integer.parseInt(tokens[0]));\n        Expression right = new NumberExpression(Integer.parseInt(tokens[2]));\n        return new AddExpression(left, right);\n    }\n}<\/code><\/pre>\n<h2>Iterator Pattern<\/h2>\n<p>The Iterator Pattern provides a way to access elements of an aggregate object sequentially without exposing the underlying representation.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">import java.util.ArrayList;\nimport java.util.List;\n\n\/\/ Iterator interface\ninterface Iterator&lt;T&gt; {\n    boolean hasNext();\n    T next();\n}\n\n\/\/ Aggregate interface\ninterface Container&lt;T&gt; {\n    Iterator&lt;T&gt; createIterator();\n}\n\n\/\/ Concrete Iterator\nclass NameIterator implements Iterator&lt;String&gt; {\n    private List&lt;String&gt; names;\n    private int index;\n\n    public NameIterator(List&lt;String&gt; names) {\n        this.names = names;\n        this.index = 0;\n    }\n\n    @Override\n    public boolean hasNext() {\n        return index &lt; names.size();\n    }\n\n    @Override\n    public String next() {\n        if (hasNext()) {\n            return names.get(index++);\n        }\n        return null;\n    }\n}\n\n\/\/ Concrete Aggregate\nclass NameRepository implements Container&lt;String&gt; {\n    private List&lt;String&gt; names;\n\n    public NameRepository() {\n        this.names = new ArrayList&lt;&gt;();\n    }\n\n    public void addName(String name) {\n        names.add(name);\n    }\n\n    @Override\n    public Iterator&lt;String&gt; createIterator() {\n        return new NameIterator(names);\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        NameRepository nameRepository = new NameRepository();\n        nameRepository.addName(&quot;Alice&quot;);\n        nameRepository.addName(&quot;Bob&quot;);\n        nameRepository.addName(&quot;Charlie&quot;);\n\n        Iterator&lt;String&gt; iterator = nameRepository.createIterator();\n        while (iterator.hasNext()) {\n            System.out.println(&quot;Name: &quot; + iterator.next());\n        }\n    }\n}<\/code><\/pre>\n<h2>Mediator Pattern<\/h2>\n<p>The Mediator Pattern defines an object that centralizes communication between objects in a system. It promotes loose coupling by ensuring that objects don't communicate directly with each other.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">import java.util.ArrayList;\nimport java.util.List;\n\n\/\/ Mediator interface\ninterface Mediator {\n    void sendMessage(String message, Colleague colleague);\n}\n\n\/\/ Colleague interface\nabstract class Colleague {\n    protected Mediator mediator;\n\n    public Colleague(Mediator mediator) {\n        this.mediator = mediator;\n    }\n\n    public abstract void receive(String message);\n\n    public abstract void send(String message);\n}\n\n\/\/ Concrete Mediator\nclass ChatRoom implements Mediator {\n    private List&lt;Colleague&gt; colleagues = new ArrayList&lt;&gt;();\n\n    @Override\n    public void sendMessage(String message, Colleague colleague) {\n        for (Colleague c : colleagues) {\n            if (c != colleague) {\n                c.receive(message);\n            }\n        }\n    }\n\n    public void addColleague(Colleague colleague) {\n        colleagues.add(colleague);\n    }\n}\n\n\/\/ Concrete Colleague\nclass User extends Colleague {\n    private String name;\n\n    public User(String name, Mediator mediator) {\n        super(mediator);\n        this.name = name;\n    }\n\n    @Override\n    public void receive(String message) {\n        System.out.println(name + &quot; received: &quot; + message);\n    }\n\n    @Override\n    public void send(String message) {\n        System.out.println(name + &quot; sent: &quot; + message);\n        mediator.sendMessage(message, this);\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        ChatRoom chatRoom = new ChatRoom();\n\n        User user1 = new User(&quot;Alice&quot;, chatRoom);\n        User user2 = new User(&quot;Bob&quot;, chatRoom);\n        User user3 = new User(&quot;Charlie&quot;, chatRoom);\n\n        chatRoom.addColleague(user1);\n        chatRoom.addColleague(user2);\n        chatRoom.addColleague(user3);\n\n        user1.send(&quot;Hello, everyone!&quot;);\n    }\n}<\/code><\/pre>\n<h2>Memento Pattern<\/h2>\n<p>The Memento Pattern provides a way to capture and externalize an object's internal state so that it can be restored to that state later.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">import java.util.ArrayList;\nimport java.util.List;\n\n\/\/ Memento class\nclass EditorMemento {\n    private final String content;\n\n    public EditorMemento(String content) {\n        this.content = content;\n    }\n\n    public String getContent() {\n        return content;\n    }\n}\n\n\/\/ Originator class\nclass TextEditor {\n    private String content;\n\n    public void write(String content) {\n        this.content = content;\n    }\n\n    public EditorMemento save() {\n        return new EditorMemento(content);\n    }\n\n    public void restore(EditorMemento memento) {\n        content = memento.getContent();\n    }\n\n    public String getContent() {\n        return content;\n    }\n}\n\n\/\/ Caretaker class\nclass History {\n    private List&lt;EditorMemento&gt; mementos = new ArrayList&lt;&gt;();\n\n    public void push(EditorMemento memento) {\n        mementos.add(memento);\n    }\n\n    public EditorMemento pop() {\n        if (!mementos.isEmpty()) {\n            int lastIndex = mementos.size() - 1;\n            EditorMemento lastMemento = mementos.get(lastIndex);\n            mementos.remove(lastIndex);\n            return lastMemento;\n        }\n        return null;\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        TextEditor textEditor = new TextEditor();\n        History history = new History();\n\n        textEditor.write(&quot;Hello, World!&quot;);\n        history.push(textEditor.save());\n\n        textEditor.write(&quot;This is a new text.&quot;);\n        history.push(textEditor.save());\n\n        textEditor.write(&quot;Memento Pattern example.&quot;);\n        System.out.println(&quot;Current Content: &quot; + textEditor.getContent());\n\n        \/\/ Restore to previous state\n        textEditor.restore(history.pop());\n        System.out.println(&quot;Restored Content: &quot; + textEditor.getContent());\n\n        \/\/ Restore to previous state\n        textEditor.restore(history.pop());\n        System.out.println(&quot;Restored Content: &quot; + textEditor.getContent());\n    }\n}<\/code><\/pre>\n<h2>Null Object Pattern<\/h2>\n<p>The Null Object Pattern provides an object as a surrogate for the lack of an object of a given type. It helps eliminate null references in your code.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">abstract class Animal {\n    protected String name;\n\n    public abstract String getName();\n}\n\n\/\/ Concrete class representing a real animal\nclass RealAnimal extends Animal {\n    public RealAnimal(String name) {\n        this.name = name;\n    }\n\n    @Override\n    public String getName() {\n        return name;\n    }\n}\n\n\/\/ Null object representing a &quot;null&quot; animal\nclass NullAnimal extends Animal {\n    @Override\n    public String getName() {\n        return &quot;No animal found&quot;;\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Animal realDog = new RealAnimal(&quot;Dog&quot;);\n        Animal nullAnimal = new NullAnimal();\n\n        System.out.println(&quot;Real Animal: &quot; + realDog.getName());\n        System.out.println(&quot;Null Animal: &quot; + nullAnimal.getName());\n    }\n}<\/code><\/pre>\n<h2>Observer Pattern<\/h2>\n<p>The Observer Pattern defines a one-to-many relationship between objects so that when one object changes state, all its dependents (observers) are notified and updated automatically. This pattern is widely used in event handling systems.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">import java.util.ArrayList;\nimport java.util.List;\n\n\/\/ Subject (Observable)\nclass WeatherStation {\n    private List&lt;Observer&gt; observers = new ArrayList&lt;&gt;();\n    private int temperature;\n\n    public void addObserver(Observer observer) {\n        observers.add(observer);\n    }\n\n    public void removeObserver(Observer observer) {\n        observers.remove(observer);\n    }\n\n    public void setTemperature(int temperature) {\n        this.temperature = temperature;\n        notifyObservers();\n    }\n\n    public void notifyObservers() {\n        for (Observer observer : observers) {\n            observer.update(temperature);\n        }\n    }\n}\n\n\/\/ Observer\ninterface Observer {\n    void update(int temperature);\n}\n\n\/\/ Concrete Observer\nclass WeatherDisplay implements Observer {\n    @Override\n    public void update(int temperature) {\n        System.out.println(&quot;Temperature is now &quot; + temperature + &quot; degrees Celsius.&quot;);\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        WeatherStation weatherStation = new WeatherStation();\n        WeatherDisplay display1 = new WeatherDisplay();\n        WeatherDisplay display2 = new WeatherDisplay();\n\n        weatherStation.addObserver(display1);\n        weatherStation.addObserver(display2);\n\n        weatherStation.setTemperature(25);\n    }\n}<\/code><\/pre>\n<h2>State Pattern<\/h2>\n<p>The State Pattern allows an object to alter its behavior when its internal state changes. It involves defining a set of state objects and switching between them as needed.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">\/\/ State interface\ninterface State {\n    void handleRequest(Context context);\n}\n\n\/\/ Concrete States\nclass StateIdle implements State {\n    @Override\n    public void handleRequest(Context context) {\n        System.out.println(&quot;Context is in the idle state.&quot;);\n        context.setState(new StateActive());\n    }\n}\n\nclass StateActive implements State {\n    @Override\n    public void handleRequest(Context context) {\n        System.out.println(&quot;Context is in the active state.&quot;);\n        context.setState(new StateIdle());\n    }\n}\n\n\/\/ Context\nclass Context {\n    private State currentState;\n\n    public Context() {\n        currentState = new StateIdle();\n    }\n\n    public void setState(State state) {\n        currentState = state;\n    }\n\n    public void request() {\n        currentState.handleRequest(this);\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Context context = new Context();\n\n        context.request(); \/\/ Transition to active state\n        context.request(); \/\/ Transition to idle state\n    }\n}<\/code><\/pre>\n<h2>Strategy Pattern<\/h2>\n<p>The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. It allows the client to choose the appropriate algorithm at runtime without altering the code that uses it.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">\/\/ Strategy interface\ninterface PaymentStrategy {\n    void pay(int amount);\n}\n\n\/\/ Concrete Strategies\nclass CreditCardPayment implements PaymentStrategy {\n    private String cardNumber;\n\n    public CreditCardPayment(String cardNumber) {\n        this.cardNumber = cardNumber;\n    }\n\n    @Override\n    public void pay(int amount) {\n        System.out.println(&quot;Paid $&quot; + amount + &quot; with credit card &quot; + cardNumber);\n    }\n}\n\nclass PayPalPayment implements PaymentStrategy {\n    private String email;\n\n    public PayPalPayment(String email) {\n        this.email = email;\n    }\n\n    @Override\n    public void pay(int amount) {\n        System.out.println(&quot;Paid $&quot; + amount + &quot; with PayPal account &quot; + email);\n    }\n}\n\n\/\/ Context\nclass ShoppingCart {\n    private PaymentStrategy paymentStrategy;\n\n    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {\n        this.paymentStrategy = paymentStrategy;\n    }\n\n    public void checkout(int totalAmount) {\n        paymentStrategy.pay(totalAmount);\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        ShoppingCart cart = new ShoppingCart();\n\n        cart.setPaymentStrategy(new CreditCardPayment(&quot;1234-5678-9876-5432&quot;));\n        cart.checkout(100);\n\n        cart.setPaymentStrategy(new PayPalPayment(&quot;example@example.com&quot;));\n        cart.checkout(50);\n    }\n}<\/code><\/pre>\n<h2>Template Method Pattern<\/h2>\n<p>The Template Method Pattern defines the skeleton of an algorithm in the superclass but lets subclasses override specific steps of the algorithm without changing its structure.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">\/\/ Abstract class defining the template method\nabstract class PaymentProcessor {\n    public void processPayment() {\n        authenticate();\n        validatePaymentInfo();\n        performPayment();\n        sendConfirmationEmail();\n    }\n\n    abstract void authenticate();\n\n    abstract void validatePaymentInfo();\n\n    abstract void performPayment();\n\n    void sendConfirmationEmail() {\n        System.out.println(&quot;Sending payment confirmation email.&quot;);\n    }\n}\n\n\/\/ Concrete subclass\nclass CreditCardPaymentProcessor extends PaymentProcessor {\n    @Override\n    void authenticate() {\n        System.out.println(&quot;Authenticating credit card payment...&quot;);\n    }\n\n    @Override\n    void validatePaymentInfo() {\n        System.out.println(&quot;Validating credit card payment information...&quot;);\n    }\n\n    @Override\n    void performPayment() {\n        System.out.println(&quot;Processing credit card payment...&quot;);\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        PaymentProcessor paymentProcessor = new CreditCardPaymentProcessor();\n        paymentProcessor.processPayment();\n    }\n}<\/code><\/pre>\n<h2>Visitor Pattern<\/h2>\n<p>The Visitor Pattern represents an operation to be performed on elements of an object structure. It lets you define a new operation without changing the classes of the elements on which it operates.<\/p>\n<p><strong>Example<\/strong><\/p>\n<pre><code class=\"language-java\">\/\/ Visitor interface\ninterface Visitor {\n    void visit(Book book);\n    void visit(Video video);\n}\n\n\/\/ Visitable interface\ninterface Visitable {\n    void accept(Visitor visitor);\n}\n\n\/\/ Concrete Visitable classes\nclass Book implements Visitable {\n    private String title;\n\n    public Book(String title) {\n        this.title = title;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    @Override\n    public void accept(Visitor visitor) {\n        visitor.visit(this);\n    }\n}\n\nclass Video implements Visitable {\n    private String title;\n\n    public Video(String title) {\n        this.title = title;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    @Override\n    public void accept(Visitor visitor) {\n        visitor.visit(this);\n    }\n}\n\n\/\/ Concrete Visitor\nclass DiscountVisitor implements Visitor {\n    @Override\n    public void visit(Book book) {\n        System.out.println(&quot;Applying a 10% discount to the book: &quot; + book.getTitle());\n    }\n\n    @Override\n    public void visit(Video video) {\n        System.out.println(&quot;Applying a 15% discount to the video: &quot; + video.getTitle());\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Visitable[] items = {new Book(&quot;Design Patterns&quot;), new Video(&quot;Java Basics&quot;)};\n        Visitor discountVisitor = new DiscountVisitor();\n\n        for (Visitable item : items) {\n            item.accept(discountVisitor);\n        }\n    }\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Behavioral design patterns focus on how objects and classes interact and communicate with each other. They deal with the responsibilities of objects and the delegation of tasks among them. These patterns help you define clear and efficient ways for objects to collaborate while keeping your codebase flexible and maintainable. Chain of Responsibility Pattern The Chain [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[29],"tags":[],"_links":{"self":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/356"}],"collection":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=356"}],"version-history":[{"count":19,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/356\/revisions"}],"predecessor-version":[{"id":1626,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=\/wp\/v2\/posts\/356\/revisions\/1626"}],"wp:attachment":[{"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=356"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=356"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ronella.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=356"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}