Rumah  >  Artikel  >  Java  >  Mencipta Kod Sempurna: Memahami Corak Penciptaan

Mencipta Kod Sempurna: Memahami Corak Penciptaan

WBOY
WBOYasal
2024-08-07 07:58:23416semak imbas

Creating the Perfect Code: Understanding Creational Patterns

Ini adalah permulaan untuk siri blog tentang Corak Reka Bentuk. Dalam blog ini, kita akan membincangkan jenis corak reka bentuk pertama, Corak Ciptaan. Di sini jenis yang termasuk dalam corak ciptaan akan dibincangkan dengan beberapa contoh dunia sebenar. Saya akan menggunakan Java sebagai bahasa pilihan saya.

Apakah Corak Reka Bentuk?

Corak reka bentuk memainkan peranan penting dalam pembangunan perisian, menyediakan penyelesaian yang terbukti kepada masalah biasa dan mempromosikan amalan terbaik. Ia seperti cetak biru pra-dibuat yang boleh anda sesuaikan untuk menyelesaikan masalah reka bentuk yang berulang dalam kod anda.

Meneroka Corak Reka Bentuk Ciptaan di Jawa

Dalam pengaturcaraan berorientasikan objek, corak reka bentuk ciptaan memainkan peranan penting kerana ia membolehkan instantiasi objek dipisahkan daripada penggunaannya dan seterusnya meningkatkan fleksibiliti dan kebolehskalaan penciptaan objek. Catatan blog ini akan menumpukan pada lima jenis utama corak reka bentuk ciptaan: Kaedah Kilang, Kilang Abstrak, Pembina, Prototaip dan Singleton. Untuk menunjukkan cara setiap satu berfungsi, kami akan menggunakan contoh dunia sebenar dalam Java.

1. Kaedah Kilang

Corak Kaedah Kilang mentakrifkan antara muka untuk mencipta objek tetapi membenarkan subkelas mengubah jenis objek yang akan dibuat. Corak ini menyokong gandingan longgar dalam Java untuk menghentikan keperluan untuk mengikat kelas khusus aplikasi ke dalam kod.

Senario kehidupan sebenar: Pertimbangkan syarikat logistik yang mengangkut barangan menggunakan pelbagai kenderaan seperti trak dan kapal. Jenis kenderaan bergantung pada mod pengangkutan yang diperlukan.

// Product Interface
interface Transport {
    void deliver();
}

// Concrete Products
class Truck implements Transport {
    @Override
    public void deliver() {
        System.out.println("Deliver by land in a truck.");
    }
}

class Ship implements Transport {
    @Override
    public void deliver() {
        System.out.println("Deliver by sea in a ship.");
    }
}

// Creator
abstract class Logistics {
    public abstract Transport createTransport();

    public void planDelivery() {
        Transport transport = createTransport();
        transport.deliver();
    }
}

// Concrete Creators
class RoadLogistics extends Logistics {
    @Override
    public Transport createTransport() {
        return new Truck();
    }
}

class SeaLogistics extends Logistics {
    @Override
    public Transport createTransport() {
        return new Ship();
    }
}

// let's call the main class
public class Main {
    public static void main(String[] args) {
        Logistics logistics = new RoadLogistics();
        logistics.planDelivery();

        logistics = new SeaLogistics();
        logistics.planDelivery();
    }
}

2. Kilang Abstrak

Corak Kilang Abstrak menyediakan antara muka untuk mencipta keluarga objek berkaitan atau bergantung tanpa menyatakan kelas konkritnya. Ia berguna apabila sistem perlu bebas daripada cara objeknya dicipta.

Senario kehidupan sebenar: Bayangkan sebuah kedai perabot yang menjual pelbagai jenis set perabot, seperti Victorian dan Modern. Setiap set termasuk produk seperti kerusi dan sofa.

// Abstract Products
interface Chair {
    void sitOn();
}

interface Sofa {
    void lieOn();
}

// Concrete Products
class VictorianChair implements Chair {
    @Override
    public void sitOn() {
        System.out.println("Sitting on a Victorian chair.");
    }
}

class ModernChair implements Chair {
    @Override
    public void sitOn() {
        System.out.println("Sitting on a Modern chair.");
    }
}

class VictorianSofa implements Sofa {
    @Override
    public void lieOn() {
        System.out.println("Lying on a Victorian sofa.");
    }
}

class ModernSofa implements Sofa {
    @Override
    public void lieOn() {
        System.out.println("Lying on a Modern sofa.");
    }
}

// Abstract Factory
interface FurnitureFactory {
    Chair createChair();
    Sofa createSofa();
}

// Concrete Factories
class VictorianFurnitureFactory implements FurnitureFactory {
    @Override
    public Chair createChair() {
        return new VictorianChair();
    }

    @Override
    public Sofa createSofa() {
        return new VictorianSofa();
    }
}

class ModernFurnitureFactory implements FurnitureFactory {
    @Override
    public Chair createChair() {
        return new ModernChair();
    }

    @Override
    public Sofa createSofa() {
        return new ModernSofa();
    }
}

// Client code
public class Main {
    private static void createFurniture(FurnitureFactory factory) {
        Chair chair = factory.createChair();
        Sofa sofa = factory.createSofa();
        chair.sitOn();
        sofa.lieOn();
    }

    public static void main(String[] args) {
        FurnitureFactory victorianFactory = new VictorianFurnitureFactory();
        createFurniture(victorianFactory);

        FurnitureFactory modernFactory = new ModernFurnitureFactory();
        createFurniture(modernFactory);
    }
}

3. Pembina

Corak Builder memisahkan pembinaan objek kompleks daripada perwakilannya, membenarkan proses pembinaan yang sama mencipta representasi yang berbeza. Ia amat berguna untuk mencipta objek dengan banyak atribut pilihan.

Senario kehidupan sebenar: Pertimbangkan sistem pesanan piza dalam talian di mana pelanggan boleh menyesuaikan piza mereka dengan pelbagai topping, saiz dan jenis kerak.

// Product
class Pizza {
    private String dough = "";
    private String sauce = "";
    private String topping = "";

    public void setDough(String dough) { this.dough = dough; }
    public void setSauce(String sauce) { this.sauce = sauce; }
    public void setTopping(String topping) { this.topping = topping; }

    @Override
    public String toString() {
        return "Pizza [dough=" + dough + ", sauce=" + sauce + ", topping=" + topping + "]";
    }
}

// Builder Interface
interface PizzaBuilder {
    void buildDough();
    void buildSauce();
    void buildTopping();
    Pizza getPizza();
}

// Concrete Builders
class HawaiianPizzaBuilder implements PizzaBuilder {
    private Pizza pizza;

    public HawaiianPizzaBuilder() {
        this.pizza = new Pizza();
    }

    @Override
    public void buildDough() { pizza.setDough("cross"); }
    @Override
    public void buildSauce() { pizza.setSauce("mild"); }
    @Override
    public void buildTopping() { pizza.setTopping("ham+pineapple"); }
    @Override
    public Pizza getPizza() { return this.pizza; }
}

class SpicyPizzaBuilder implements PizzaBuilder {
    private Pizza pizza;

    public SpicyPizzaBuilder() {
        this.pizza = new Pizza();
    }

    @Override
    public void buildDough() { pizza.setDough("pan baked"); }
    @Override
    public void buildSauce() { pizza.setSauce("hot"); }
    @Override
    public void buildTopping() { pizza.setTopping("pepperoni+salami"); }
    @Override
    public Pizza getPizza() { return this.pizza; }
}

// Director
class Waiter {
    private PizzaBuilder pizzaBuilder;

    public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilder = pb; }
    public Pizza getPizza() { return pizzaBuilder.getPizza(); }

    public void constructPizza() {
        pizzaBuilder.buildDough();
        pizzaBuilder.buildSauce();
        pizzaBuilder.buildTopping();
    }
}

// Client code
public class Main {
    public static void main(String[] args) {
        Waiter waiter = new Waiter();
        PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
        PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();

        waiter.setPizzaBuilder(hawaiianPizzaBuilder);
        waiter.constructPizza();
        Pizza pizza1 = waiter.getPizza();
        System.out.println("Pizza built: " + pizza1);

        waiter.setPizzaBuilder(spicyPizzaBuilder);
        waiter.constructPizza();
        Pizza pizza2 = waiter.getPizza();
        System.out.println("Pizza built: " + pizza2);
    }
}

4. Prototaip

Corak Prototaip digunakan untuk mencipta objek baharu dengan menyalin objek sedia ada, dikenali sebagai prototaip. Corak ini berguna apabila kos mencipta objek baharu mahal.

Senario kehidupan sebenar: Fikirkan editor grafik tempat anda boleh membuat, menduplikasi dan mengedit bentuk.

import java.util.HashMap;
import java.util.Map;

// Prototype
abstract class Shape implements Cloneable {
    private String id;
    protected String type;

    abstract void draw();

    public String getType() { return type; }
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public Object clone() {
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return clone;
    }
}

// Concrete Prototypes
class Rectangle extends Shape {
    public Rectangle() { type = "Rectangle"; }
    @Override
    public void draw() { System.out.println("Drawing a Rectangle."); }
}

class Circle extends Shape {
    public Circle() { type = "Circle"; }
    @Override
    public void draw() { System.out.println("Drawing a Circle."); }
}

// Prototype Registry
class ShapeCache {
    private static Map<String, Shape> shapeMap = new HashMap<>();

    public static Shape getShape(String shapeId) {
        Shape cachedShape = shapeMap.get(shapeId);
        return (Shape) cachedShape.clone();
    }

    public static void loadCache() {
        Rectangle rectangle = new Rectangle();
        rectangle.setId("1");
        shapeMap.put(rectangle.getId(), rectangle);

        Circle circle = new Circle();
        circle.setId("2");
        shapeMap.put(circle.getId(), circle);
    }
}

// Client code
public class Main {
    public static void main(String[] args) {
        ShapeCache.loadCache();

        Shape clonedShape1 = ShapeCache.getShape("1");
        System.out.println("Shape: " + clonedShape1.getType());

        Shape clonedShape2 = ShapeCache.getShape("2");
        System.out.println("Shape: " + clonedShape2.getType());
    }
}

5. Singleton

Corak Singleton memastikan kelas hanya mempunyai satu tika dan menyediakan titik global akses kepadanya. Corak ini biasanya digunakan untuk pengelogan, caching dan kumpulan benang.

Senario kehidupan sebenar: Bayangkan spooler pencetak di mana hanya satu contoh harus mengurus semua kerja cetakan.

class PrinterSpooler {
    private static PrinterSpooler instance;

    private PrinterSpooler() {
        // private constructor to prevent instantiation
    }

    public static PrinterSpooler getInstance() {
        if (instance == null) {
            instance = new PrinterSpooler();
        }
        return instance;
    }

    public void print(String document) {
        System.out.println("Printing document: " + document);
    }
}

// Client code
public class Main {
    public static void main(String[] args) {
        PrinterSpooler spooler1 = PrinterSpooler.getInstance();
        PrinterSpooler spooler2 = PrinterSpooler.getInstance();

        spooler1.print("Document 1");
        spooler2.print("Document 2");

        System.out.println("Are both spoolers the same instance? " + (spooler1 == spooler2));
    }
}

Rujukan

https://refactoring.guru/

https://www.javatpoint.com/design-patterns-in-java

https://www.digitalocean.com/community/tutorials/java-design-patterns-example-tutorial

Atas ialah kandungan terperinci Mencipta Kod Sempurna: Memahami Corak Penciptaan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn