Tôi có một câu hỏi không còn là một câu hỏi thiết kế nữa. Tôi có một lớp định nghĩa một loạt các hàm. Tuy nhiên, tôi muốn rằng hành vi của một số chức năng có thể thay đổi trong thời gian chạy - hoặc ít nhất là làm việc như một giao diện plugin trong thời gian thiết kế. ví dụ:Các lớp PHP đa hình/có thể cắm được
class MyClass {
public function doSomething();
}
$obj = new MyClass();
// PSEUDO CODE
$obj->doSomething = doSomethingElse;
$obj->doSomething(); // does something else
Tôi đã có nhiều ý tưởng khác nhau về cách triển khai một cái gì đó như thế này trong mã "thực". Tuy nhiên, tôi không hoàn toàn chắc chắn, đó là con đường đúng đắn để đi. Lần đầu tiên tôi nghĩ rằng tôi có thể sử dụng một giao diện cho mục đích này.
interface IDoSomethingInterface {
public function doSomething();
}
class DoSomethingClass implements IDoSomethingInterface
{
public function doSomething()
{
// I do something!
}
}
class DoSomethingElseClass implements IDoSomethingInterface
{
public function doSomething()
{
// I actually do something else!
}
}
class MyClass {
public doSomething(IDoSomething $doSomethingProvider)
{
$doSomethingProvider->doSomething();
}
}
$obj = new MyClass();
$doSomethingProvider = new DoSomethingClass();
$doSomethingElseProvider = new DoSomethingElseClass();
$obj->doSomething($doSomethingProvider); // I do something!
$obj->doSomething($doSomethingElseProvider); // I do something else!
Cách tiếp cận này có thể được mở rộng để không có nhà cung cấp doSomething được truyền làm tham số, nhưng để đặt thành đối tượng hoặc thậm chí là thành viên của lớp. Tuy nhiên, tôi không thích rằng tôi phải tạo một thể hiện của lớp n mà thậm chí không chứa một biến thành viên duy nhất và phương thức duy nhất có thể dễ dàng là một hàm lớp tĩnh. Không cần một đối tượng tại thời điểm đó. Tôi sau đó sẽ cố gắng sử dụng các biến chức năng - nhưng tôi sẽ rơi ra khỏi OOP sau đó, mà tôi không thích hoặc. Câu hỏi của tôi là: đó là cách tốt nhất để thực hiện một hệ thống như tôi đã mô tả? Bạn sẽ thử hoặc sử dụng phương pháp nào? Có điều gì rõ ràng tôi có thể không nghĩ đến? Hay tôi chỉ nên đi với cách tiếp cận giao diện và cảm giác tồi tệ của tôi về việc tạo ra những vật thể 'thân mật' chỉ là một thứ quý giá ?! Tôi tò mò về câu trả lời của bạn!
Edit:
Bởi vì tôi thực sự quan tâm đến việc làm rõ nếu điều này thực sự là (hoặc nên là) một nhà nước hoặc một mẫu chiến lược, tôi sẽ đi vào một số chi tiết thêm về việc thực hiện. Tôi có một lớp cơ sở của các bộ sưu tập mà từ đó tôi lấy được các triển khai cụ thể khác nhau. Tôi muốn để có thể chọn một yếu tố duy nhất từ bất kỳ thực hiện cụ thể - tuy nhiên, tôi muốn có thể tự động thay đổi như thế nào yếu tố này được chọn từ bộ sưu tập, ví dụ:
class MyCollection implements Countable, ArrayAcces, Iterator
{
// Collection Implementation
public function select(ISelectionStrategy $strategy)
{
return $strategy->select($this);
}
}
interface ISelectionStrategy
{
public function select(MyCollection $collection);
}
class AlphaSelectionStrategy implements ISelectionStrategy
{
public function select(MyCollection $collection);
{
reset($collection);
if (current($collection))
return current($collection);
else
return null;
}
}
class OmegaSelectionStrategy implements ISelectionStrategy
{
public function select(MyCollection $collection)
{
end($collection);
if (current($collection))
return current($collection)
else
return null;
}
}
class RandomSelectionStrategy implements ISelectionStrategy
{
public function select(MyCollection $collection)
{
if (!count($collection))
return null;
$rand = rand(0, count($collection)-1);
reset($collection);
while($rand-- > 0)
{
next($collection);
}
return current($collection);
}
}
$collection = new MyCollection();
$randomStrategy = new RandomSelectionStrategy();
$alphaStrategy = new AlphaSelectionStrategy();
$omegaStrategy = new OmegaSelectionStrategy();
$collection->select($alphaStrategy); // return first element, or null if none
$collection->select($omegaStrategy); // return last element, or null if none
$collection->select($randomStrategy); // return random element, or null if none
này là cơ bản những gì tôi muốn đạt được . Đây có phải là thực hiện mô hình chiến lược hay mô hình trạng thái hơn nữa - mặc dù tôi đã sử dụng chiến lược hạn vì nó vẫn phù hợp hơn trong trường hợp này. Theo như tôi hiểu chiến lược và mô hình nhà nước một cách cơ bản giống nhau, ngoại trừ ý định của họ là khác nhau. Liên kết được cung cấp bởi Gordon nói rằng ý định của một mẫu trạng thái là "Cho phép một đối tượng thay đổi hành vi của nó khi trạng thái nội tại của nó thay đổi" - nhưng đây không phải là trường hợp ở đây. Những gì tôi muốn là để có thể nói cho lớp MyCollection của tôi "sử dụng thuật toán này hoặc để cho tôi một phần tử" - không "cho tôi một yếu tố bằng cách sử dụng một thuật toán mà bạn xác định thông qua trạng thái của riêng bạn". Hy vọng ai đó có thể làm rõ điều này!
Trân trọng, Daniel
+1, nụ cười đó sẽ là kết thúc của tôi. xP –
Vâng, bạn đã tự trả lời câu hỏi của mình. Bạn không muốn quản lý các tiểu bang. Bạn muốn trao đổi những hành vi đơn lẻ, vì vậy Chiến lược là thích hợp. Trên một sidenote, vì bạn có vẻ là người Đức, tôi có thể giới thiệu cuốn sách phpdesignpatterns.de – Gordon