Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

การนำ Open/Closed Principle ไปใช้ใน C#

Open/Closed Principle (OCP) คือหลักการที่ว่า "Software entities (classes, modules, functions) ควรเปิดให้ขยาย (Open for extension) แต่ปิดต่อการแก้ไข (Closed for modification)"

หมายความ: เมื่อต้องการเพิ่มฟังก์ชันใหม่ ควรเพิ่มโค้ดใหม่ (เช่น สร้างคลาสใหม่) แทนที่จะแก้ไขโค้ดเดิมที่ทำงานอยู่แล้ว

ตัวอย่าง: ก่อนใช้ OCP (Violation)

public class Rectangle
{
    public int Width { get; set; }
    public int Height { get; set; }
}

public class Circle
{
    public double Radius { get; set; }
}

// ปัญหา: ทุกครั้งเพิ่ม Shape ใหม่ ต้องแก้ไข CombinedAreaCalculator
public class CombinedAreaCalculator
{
    public double Area(object[] shapes)
    {
        double area = 0;
        foreach (var shape in shapes)
        {
            if (shape is Rectangle r)
                area += r.Width * r.Height;
            else if (shape is Circle c)
                area += c.Radius * c.Radius * Math.PI;
            // ถ้าเพิ่ม Triangle ต้องมาแก้ if-else ที่นี่!
        }
        return area;
    }
}

ตัวอย่าง: หลังใช้ OCP (Compliant)

// 1. Abstract Base Class / Interface
public abstract class Shape
{
    public abstract double Area();
}

// 2. Concrete Implementations
public class Rectangle : Shape
{
    public int Width { get; set; }
    public int Height { get; set; }
    public override double Area() => Width * Height;
}

public class Circle : Shape
{
    public double Radius { get; set; }
    public override double Area() => Radius * Radius * Math.PI;
}

// 3. เพิ่ม Shape ใหม่ได้โดยไม่แก้ Calculator
public class Triangle : Shape
{
    public double Base { get; set; }
    public double Height { get; set; }
    public override double Area() => 0.5 * Base * Height;
}

// 4. Calculator ปิดต่อการแก้ไข เปิดต่อการขยาย
public class CombinedAreaCalculator
{
    public double Area(Shape[] shapes)
    {
        double area = 0;
        foreach (var shape in shapes)
        {
            area += shape.Area(); // เรียก Polymorphism
        }
        return area;
    }
}

ประโยชน์

  • ลดความเสี่ยงการทำให้โค้ดเดิมเสีย (Regression)
  • รองรับการเพิ่มฟีเจอร์ใหม่ได้ง่าย
  • โค้ดอ่านง่าย รักษาได้ง่าย (Maintainable)
  • สอดคล้องกับ Polymorphism และ Abstraction

เทคนิคอื่นๆ

  • ใช้ Strategy Pattern สำหรับอัลกอริทึมที่เปลี่ยนแปลงได้
  • ใช้ Decorator Pattern สำหรับเพิ่มพฤติกรรมโดยไม่แก้คลาสเดิม
  • ใช้ interface แทน Abstract Class หากไม่ต้องการ Base Implementation