
الشفرة "الإلهية" هي مصطلح عالي الصوت قد يبدو كعنوان أصفر ، ولكن مع ذلك ، سيتم مناقشة هذا الرمز بالتحديد: الأجزاء التي يتكون منها وكيفية كتابته. هذه قصة عن جهودي لضمان عدم عودة المهام مع مراجعة الكود مع ملاحظة: "All * * nya - redo."
ليس لدي تعليم متخصص ، وكان علي أن أتعلم البرمجة عمليًا ، من خلال الأخطاء والجروح والكدمات. كنت أعمل باستمرار على تحسين جودة الشفرة المكتوبة ، لقد وضعت بعض القواعد التي يجب أن تلتزم بها. اريد مشاركتها
كود الله - اختصار المختصر - كود مكتوب وفقا لمبادئ الفهم ، تمارين الهدف ، قانون ديميتر والصلبة. شخص يعرفونه جميعًا ، التقى شخص ما ببعضهم فقط ، لكننا سننظر في كل مكون من اختصار. أنا لا أضع هدفي للغوص في كل مجموعة من القواعد بالتفصيل ، حيث تم تناولها عدة مرات على الإنترنت. بدلاً من ذلك ، أقدم ضغطًا من تجربتي الخاصة.
GRASP
تسعة قوالب لتعيين المسؤوليات للفئات والكائنات. لراحة التذكر ، أقسمهم إلى مجموعتين فرعيتين:
- في المجموعة الفرعية الأولى ، يمكننا تمييز القواعد التي تسمح لك بكتابة الوحدات الذرية التي تم اختبارها وتعديلها بشكل جيد. لا تتعلق هذه القواعد كثيرًا بالمسؤولية ، ولكن دعنا نقول عن خصائص الوحدات: الاقتران الضعيف ، الالتصاق القوي ، تعدد الأشكال ، مقاومة التغييرات. بالنسبة لي ، تجاوزت هذه القواعد مع SOLID ، المزيد عن هذا في الجزء المقابل.
- المجموعة الفرعية الثانية هي بالفعل قوالب أكثر وضوحًا تخبرنا عن من يقوم بإنشاء الكائنات ("المنشئ" - الاسم الجماعي لأنماط المصنع) ، وكيفية تقليل الاتصال بين الوحدات (باستخدام أنماط "وحدة التحكم" و "وسيط") ، لمن تفوض المسؤوليات الفردية (خبير معلومات) وماذا تفعل إذا كنت أحب DDD وفي نفس الوقت اقتران منخفض (خيال خالص).
اقرأ المزيد
هنا .
الجمباز الكائن
مجموعة من قواعد تنفيذ التعليمات البرمجية التي تشبه إلى حد كبير مدونة CodeStyle للقوانين. هناك أيضا تسعة منهم. سأتحدث عن ثلاثة أحاول متابعتها في عملي اليومي (المعدل قليلاً) ، ويمكن قراءة الباقي في
المصدر الأصلي .
- لا يزيد طول الطريقة عن 15 LOC ، ولا يزيد عدد الطرق في الفصل عن 15 ، ولا يزيد عدد الفئات في مساحة اسم واحدة عن 15. بالإضافة إلى ذلك ، تعد الفئات والطرق الطويلة إشارة على انتهاك SRP (المزيد عن هذا أدناه).
- حد أقصى من التداخل لكل طريقة.
public function processItems(array items)
{
// 0
foreach (items as item) {
// 1
for (i = 0; i < 5; i++) {
// 2
… process item 5 times …
}
}
}
item
.
public function processItems(array items)
{
// 0
foreach (items as item) {
// 1
this.processItem(item);
}
}
public function processItem(Item item)
{
// 0
for (i = 0; i < 5; i++) {
// 1
… process item 5 times …
}
}
-, — , , . else
, .
public function processSomeDto(SomeDtoClass dto)
{
if (predicat) {
throw new Exception(‘predicat is failed’);
} else {
return this.dtoProcessor.process(dto);
}
}
:
public function processSomeDto(SomeDtoClass dto)
{
if (predicat) {
throw new Exception(‘predicat is failed’);
}
return this.dtoProcessor.process(dto);
}
, .
GRASP’a. , .

: B, . . :
- .
- , .
- .
- , .
. , .
this.objectB.objectC.getSomeStuff()
, , .
. -, . :
public function methodA()
{
spawnedObject = this.factory.spawn();
spawnedObject.performSomeStuff();
}
:
public function methodA()
{
this.factory.spawn().performSomeStuff();
}
, - .
public function methodA()
{
this.processor.process(this.factory.spawn());
}
: DTO/Entity. .
public function methodA(SomeDtoClass dto)
{
dto.getAddress().getCity();
}
, , . , , , ,
getCity DTO Address
dto
.
SOLID
SRP, OCP, LSP, ISP, DIP — , .
SRP — . — , . High Cohesion GRASP’a.
: , — - (MVC). - - , SRP.
public function indexAction(RequestInterface request): ResponseInterface
{
requestDto = this.requestTransformer.transform(request);
responseDto = this.requestProcessor.process(requestDto);
return this.responseTransformer.transform(responseDto);
}
- , , — . , , , , .
OCP — -. , , .
- , if/switch. , . . — . , .
resolver, .
final lass Resolver implements ResolverInterface
{
private mapping;
public function Resolver(array mapping)
{
this.mapping = mapping;
}
public function resolve(Item item)
{
return this.mapping[item.getType()].perform(item);
}
}
, . : , final, abstract, .
LSP — . , .
:
- ( ).
- ( , , , ).
- ( ).
- , ( , , , ).
class ParentClass
{
public function someMethod(string param1)
{
// some logic
}
}
class ChildClass extends ParentClass
{
public function someMethod(string param1, string param2)
{
if (param1 == '') {
throw new ExtraException();
}
// some logic
}
}
someMethod
ChildClass
(
param2
),
param1
, . ,
ParentClass
ChildClass
.
ISP — . , . , , , , — , .
interface DuckInterface
{
public function swim(): void;
public function fly(): void;
}
class MallardDuck implements DuckInterface
{
public function swim(): void
{
// some logic
}
public function fly(): void
{
// some logic
}
}
class RubberDuck implements DuckInterface
{
public function swim(): void
{
// some logic
}
public function fly(): void
{
// can't fly :(
}
}
RubberDuck
DuckInterface
. , , ,
DuckInterface
FlyableInterface
SwimableInterface
, .
DIP — . , , ( , ).
new
.
class DIPViolation
{
public function badMethod()
{
someService = new SomeService(445, 'second params');
// operations with someService
}
}
- , . . :
class DIP
{
private $service;
public function DIP(SomeServiceInterface $someService)
{
$this->someService = $someService;
}
public function goodMethod()
{
// operations with someService
}
}
, , , , «» . , . , , , «», , :)